LCOV - code coverage report
Current view: top level - 11 - concepts (source / functions) Hit Total Coverage
Test: jami-coverage-filtered.info Lines: 0 6 0.0 %
Date: 2026-04-01 09:29:43 Functions: 0 2 0.0 %

          Line data    Source code
       1             : // <concepts> -*- C++ -*-
       2             : 
       3             : // Copyright (C) 2019-2021 Free Software Foundation, Inc.
       4             : //
       5             : // This file is part of the GNU ISO C++ Library.  This library is free
       6             : // software; you can redistribute it and/or modify it under the
       7             : // terms of the GNU General Public License as published by the
       8             : // Free Software Foundation; either version 3, or (at your option)
       9             : // any later version.
      10             : 
      11             : // This library is distributed in the hope that it will be useful,
      12             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             : // GNU General Public License for more details.
      15             : 
      16             : // Under Section 7 of GPL version 3, you are granted additional
      17             : // permissions described in the GCC Runtime Library Exception, version
      18             : // 3.1, as published by the Free Software Foundation.
      19             : 
      20             : // You should have received a copy of the GNU General Public License and
      21             : // a copy of the GCC Runtime Library Exception along with this program;
      22             : // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      23             : // <http://www.gnu.org/licenses/>.
      24             : 
      25             : /** @file include/concepts
      26             :  *  This is a Standard C++ Library header.
      27             :  *  @ingroup concepts
      28             :  */
      29             : 
      30             : #ifndef _GLIBCXX_CONCEPTS
      31             : #define _GLIBCXX_CONCEPTS 1
      32             : 
      33             : #if __cplusplus > 201703L && __cpp_concepts >= 201907L
      34             : 
      35             : #pragma GCC system_header
      36             : 
      37             : /**
      38             :  * @defgroup concepts Concepts
      39             :  * @ingroup utilities
      40             :  *
      41             :  * Concepts for checking type requirements.
      42             :  */
      43             : 
      44             : #include <type_traits>
      45             : 
      46             : namespace std _GLIBCXX_VISIBILITY(default)
      47             : {
      48             : _GLIBCXX_BEGIN_NAMESPACE_VERSION
      49             : 
      50             : #define __cpp_lib_concepts 202002L
      51             : 
      52             :   // [concepts.lang], language-related concepts
      53             : 
      54             :   namespace __detail
      55             :   {
      56             :     template<typename _Tp, typename _Up>
      57             :       concept __same_as = std::is_same_v<_Tp, _Up>;
      58             :   } // namespace __detail
      59             : 
      60             :   /// [concept.same], concept same_as
      61             :   template<typename _Tp, typename _Up>
      62             :     concept same_as
      63             :       = __detail::__same_as<_Tp, _Up> && __detail::__same_as<_Up, _Tp>;
      64             : 
      65             :   /// [concept.derived], concept derived_from
      66             :   template<typename _Derived, typename _Base>
      67             :     concept derived_from = __is_base_of(_Base, _Derived)
      68             :       && is_convertible_v<const volatile _Derived*, const volatile _Base*>;
      69             : 
      70             :   /// [concept.convertible], concept convertible_to
      71             :   template<typename _From, typename _To>
      72             :     concept convertible_to = is_convertible_v<_From, _To>
      73             :       && requires { static_cast<_To>(std::declval<_From>()); };
      74             : 
      75             :   /// [concept.commonref], concept common_reference_with
      76             :   template<typename _Tp, typename _Up>
      77             :     concept common_reference_with
      78             :       = same_as<common_reference_t<_Tp, _Up>, common_reference_t<_Up, _Tp>>
      79             :       && convertible_to<_Tp, common_reference_t<_Tp, _Up>>
      80             :       && convertible_to<_Up, common_reference_t<_Tp, _Up>>;
      81             : 
      82             :   /// [concept.common], concept common_with
      83             :   template<typename _Tp, typename _Up>
      84             :     concept common_with
      85             :       = same_as<common_type_t<_Tp, _Up>, common_type_t<_Up, _Tp>>
      86             :       && requires {
      87             :         static_cast<common_type_t<_Tp, _Up>>(std::declval<_Tp>());
      88             :         static_cast<common_type_t<_Tp, _Up>>(std::declval<_Up>());
      89             :       }
      90             :       && common_reference_with<add_lvalue_reference_t<const _Tp>,
      91             :                                add_lvalue_reference_t<const _Up>>
      92             :       && common_reference_with<add_lvalue_reference_t<common_type_t<_Tp, _Up>>,
      93             :                                common_reference_t<
      94             :                                  add_lvalue_reference_t<const _Tp>,
      95             :                                  add_lvalue_reference_t<const _Up>>>;
      96             : 
      97             :   // [concepts.arithmetic], arithmetic concepts
      98             : 
      99             :   template<typename _Tp>
     100             :     concept integral = is_integral_v<_Tp>;
     101             : 
     102             :   template<typename _Tp>
     103             :     concept signed_integral = integral<_Tp> && is_signed_v<_Tp>;
     104             : 
     105             :   template<typename _Tp>
     106             :     concept unsigned_integral = integral<_Tp> && !signed_integral<_Tp>;
     107             : 
     108             :   template<typename _Tp>
     109             :     concept floating_point = is_floating_point_v<_Tp>;
     110             : 
     111             :   namespace __detail
     112             :   {
     113             :     template<typename _Tp>
     114             :       using __cref = const remove_reference_t<_Tp>&;
     115             : 
     116             :       template<typename _Tp>
     117             :         concept __class_or_enum
     118             :           = is_class_v<_Tp> || is_union_v<_Tp> || is_enum_v<_Tp>;
     119             :   } // namespace __detail
     120             : 
     121             :   /// [concept.assignable], concept assignable_from
     122             :   template<typename _Lhs, typename _Rhs>
     123             :     concept assignable_from
     124             :       = is_lvalue_reference_v<_Lhs>
     125             :       && common_reference_with<__detail::__cref<_Lhs>, __detail::__cref<_Rhs>>
     126             :       && requires(_Lhs __lhs, _Rhs&& __rhs) {
     127             :         { __lhs = static_cast<_Rhs&&>(__rhs) } -> same_as<_Lhs>;
     128             :       };
     129             : 
     130             :   /// [concept.destructible], concept destructible
     131             :   template<typename _Tp>
     132             :     concept destructible = is_nothrow_destructible_v<_Tp>;
     133             : 
     134             :   /// [concept.constructible], concept constructible_from
     135             :   template<typename _Tp, typename... _Args>
     136             :     concept constructible_from
     137             :       = destructible<_Tp> && is_constructible_v<_Tp, _Args...>;
     138             : 
     139             :   /// [concept.defaultinitializable], concept default_initializable
     140             :   template<typename _Tp>
     141             :     concept default_initializable = constructible_from<_Tp>
     142             :       && requires
     143             :       {
     144             :         _Tp{};
     145             :         (void) ::new _Tp;
     146             :       };
     147             : 
     148             :   /// [concept.moveconstructible], concept move_constructible
     149             :   template<typename _Tp>
     150             :     concept move_constructible
     151             :     = constructible_from<_Tp, _Tp> && convertible_to<_Tp, _Tp>;
     152             : 
     153             :   /// [concept.copyconstructible], concept copy_constructible
     154             :   template<typename _Tp>
     155             :     concept copy_constructible
     156             :       = move_constructible<_Tp>
     157             :       && constructible_from<_Tp, _Tp&> && convertible_to<_Tp&, _Tp>
     158             :       && constructible_from<_Tp, const _Tp&> && convertible_to<const _Tp&, _Tp>
     159             :       && constructible_from<_Tp, const _Tp> && convertible_to<const _Tp, _Tp>;
     160             : 
     161             :   // [concept.swappable], concept swappable
     162             : 
     163             :   namespace ranges
     164             :   {
     165             :     namespace __cust_swap
     166             :     {
     167             :       template<typename _Tp> void swap(_Tp&, _Tp&) = delete;
     168             : 
     169             :       template<typename _Tp, typename _Up>
     170             :         concept __adl_swap
     171             :           = (__detail::__class_or_enum<remove_reference_t<_Tp>>
     172             :             || __detail::__class_or_enum<remove_reference_t<_Up>>)
     173             :           && requires(_Tp&& __t, _Up&& __u) {
     174             :             swap(static_cast<_Tp&&>(__t), static_cast<_Up&&>(__u));
     175             :           };
     176             : 
     177             :       struct _Swap
     178             :       {
     179             :       private:
     180             :         template<typename _Tp, typename _Up>
     181             :           static constexpr bool
     182             :           _S_noexcept()
     183             :           {
     184             :             if constexpr (__adl_swap<_Tp, _Up>)
     185             :               return noexcept(swap(std::declval<_Tp>(), std::declval<_Up>()));
     186             :             else
     187             :               return is_nothrow_move_constructible_v<remove_reference_t<_Tp>>
     188             :                    && is_nothrow_move_assignable_v<remove_reference_t<_Tp>>;
     189             :           }
     190             : 
     191             :       public:
     192             :         template<typename _Tp, typename _Up>
     193             :           requires __adl_swap<_Tp, _Up>
     194             :           || (same_as<_Tp, _Up> && is_lvalue_reference_v<_Tp>
     195             :               && move_constructible<remove_reference_t<_Tp>>
     196             :               && assignable_from<_Tp, remove_reference_t<_Tp>>)
     197             :           constexpr void
     198           0 :           operator()(_Tp&& __t, _Up&& __u) const
     199             :           noexcept(_S_noexcept<_Tp, _Up>())
     200             :           {
     201             :             if constexpr (__adl_swap<_Tp, _Up>)
     202             :               swap(static_cast<_Tp&&>(__t), static_cast<_Up&&>(__u));
     203             :             else
     204             :               {
     205           0 :                 auto __tmp = static_cast<remove_reference_t<_Tp>&&>(__t);
     206           0 :                 __t = static_cast<remove_reference_t<_Tp>&&>(__u);
     207           0 :                 __u = static_cast<remove_reference_t<_Tp>&&>(__tmp);
     208           0 :               }
     209           0 :           }
     210             : 
     211             :         template<typename _Tp, typename _Up, size_t _Num>
     212             :           requires requires(const _Swap& __swap, _Tp& __e1, _Up& __e2) {
     213             :             __swap(__e1, __e2);
     214             :           }
     215             :           constexpr void
     216             :           operator()(_Tp (&__e1)[_Num], _Up (&__e2)[_Num]) const
     217             :           noexcept(noexcept(std::declval<const _Swap&>()(*__e1, *__e2)))
     218             :           {
     219             :             for (size_t __n = 0; __n < _Num; ++__n)
     220             :               (*this)(__e1[__n], __e2[__n]);
     221             :           }
     222             :       };
     223             :     } // namespace __cust_swap
     224             : 
     225             :     inline namespace __cust
     226             :     {
     227             :       inline constexpr __cust_swap::_Swap swap{};
     228             :     } // inline namespace __cust
     229             :   } // namespace ranges
     230             : 
     231             :   template<typename _Tp>
     232             :     concept swappable
     233             :       = requires(_Tp& __a, _Tp& __b) { ranges::swap(__a, __b); };
     234             : 
     235             :   template<typename _Tp, typename _Up>
     236             :     concept swappable_with = common_reference_with<_Tp, _Up>
     237             :       && requires(_Tp&& __t, _Up&& __u) {
     238             :         ranges::swap(static_cast<_Tp&&>(__t), static_cast<_Tp&&>(__t));
     239             :         ranges::swap(static_cast<_Up&&>(__u), static_cast<_Up&&>(__u));
     240             :         ranges::swap(static_cast<_Tp&&>(__t), static_cast<_Up&&>(__u));
     241             :         ranges::swap(static_cast<_Up&&>(__u), static_cast<_Tp&&>(__t));
     242             :       };
     243             : 
     244             :   // [concepts.object], Object concepts
     245             : 
     246             :   template<typename _Tp>
     247             :     concept movable = is_object_v<_Tp> && move_constructible<_Tp>
     248             :       && assignable_from<_Tp&, _Tp> && swappable<_Tp>;
     249             : 
     250             :   template<typename _Tp>
     251             :     concept copyable = copy_constructible<_Tp> && movable<_Tp>
     252             :       && assignable_from<_Tp&, _Tp&> && assignable_from<_Tp&, const _Tp&>
     253             :       && assignable_from<_Tp&, const _Tp>;
     254             : 
     255             :   template<typename _Tp>
     256             :     concept semiregular = copyable<_Tp> && default_initializable<_Tp>;
     257             : 
     258             :   // [concepts.compare], comparison concepts
     259             : 
     260             :   // [concept.booleantestable], Boolean testability
     261             :   namespace __detail
     262             :   {
     263             :     template<typename _Tp>
     264             :       concept __boolean_testable_impl = convertible_to<_Tp, bool>;
     265             : 
     266             :     template<typename _Tp>
     267             :       concept __boolean_testable
     268             :         = __boolean_testable_impl<_Tp>
     269             :           && requires(_Tp&& __t)
     270             :           { { !static_cast<_Tp&&>(__t) } -> __boolean_testable_impl; };
     271             :   } // namespace __detail
     272             : 
     273             :   // [concept.equalitycomparable], concept equality_comparable
     274             : 
     275             :   namespace __detail
     276             :   {
     277             :     template<typename _Tp, typename _Up>
     278             :       concept __weakly_eq_cmp_with
     279             :         = requires(__detail::__cref<_Tp> __t, __detail::__cref<_Up> __u) {
     280             :           { __t == __u } -> __boolean_testable;
     281             :           { __t != __u } -> __boolean_testable;
     282             :           { __u == __t } -> __boolean_testable;
     283             :           { __u != __t } -> __boolean_testable;
     284             :         };
     285             :   } // namespace __detail
     286             : 
     287             :   template<typename _Tp>
     288             :     concept equality_comparable = __detail::__weakly_eq_cmp_with<_Tp, _Tp>;
     289             : 
     290             :   template<typename _Tp, typename _Up>
     291             :     concept equality_comparable_with
     292             :       = equality_comparable<_Tp> && equality_comparable<_Up>
     293             :       && common_reference_with<__detail::__cref<_Tp>, __detail::__cref<_Up>>
     294             :       && equality_comparable<common_reference_t<__detail::__cref<_Tp>,
     295             :                                                 __detail::__cref<_Up>>>
     296             :       && __detail::__weakly_eq_cmp_with<_Tp, _Up>;
     297             : 
     298             :   namespace __detail
     299             :   {
     300             :     template<typename _Tp, typename _Up>
     301             :       concept __partially_ordered_with
     302             :         = requires(const remove_reference_t<_Tp>& __t,
     303             :                    const remove_reference_t<_Up>& __u) {
     304             :           { __t <  __u } -> __boolean_testable;
     305             :           { __t >  __u } -> __boolean_testable;
     306             :           { __t <= __u } -> __boolean_testable;
     307             :           { __t >= __u } -> __boolean_testable;
     308             :           { __u <  __t } -> __boolean_testable;
     309             :           { __u >  __t } -> __boolean_testable;
     310             :           { __u <= __t } -> __boolean_testable;
     311             :           { __u >= __t } -> __boolean_testable;
     312             :         };
     313             :   } // namespace __detail
     314             : 
     315             :   // [concept.totallyordered], concept totally_ordered
     316             :   template<typename _Tp>
     317             :     concept totally_ordered
     318             :       = equality_comparable<_Tp>
     319             :       && __detail::__partially_ordered_with<_Tp, _Tp>;
     320             : 
     321             :   template<typename _Tp, typename _Up>
     322             :     concept totally_ordered_with
     323             :       = totally_ordered<_Tp> && totally_ordered<_Up>
     324             :       && equality_comparable_with<_Tp, _Up>
     325             :       && totally_ordered<common_reference_t<__detail::__cref<_Tp>,
     326             :                                             __detail::__cref<_Up>>>
     327             :       && __detail::__partially_ordered_with<_Tp, _Up>;
     328             : 
     329             :   template<typename _Tp>
     330             :     concept regular = semiregular<_Tp> && equality_comparable<_Tp>;
     331             : 
     332             :   // [concepts.callable], callable concepts
     333             : 
     334             :   /// [concept.invocable], concept invocable
     335             :   template<typename _Fn, typename... _Args>
     336             :     concept invocable = is_invocable_v<_Fn, _Args...>;
     337             : 
     338             :   /// [concept.regularinvocable], concept regular_invocable
     339             :   template<typename _Fn, typename... _Args>
     340             :     concept regular_invocable = invocable<_Fn, _Args...>;
     341             : 
     342             :   /// [concept.predicate], concept predicate
     343             :   template<typename _Fn, typename... _Args>
     344             :     concept predicate = regular_invocable<_Fn, _Args...>
     345             :       && __detail::__boolean_testable<invoke_result_t<_Fn, _Args...>>;
     346             : 
     347             :   /// [concept.relation], concept relation
     348             :   template<typename _Rel, typename _Tp, typename _Up>
     349             :     concept relation
     350             :       = predicate<_Rel, _Tp, _Tp> && predicate<_Rel, _Up, _Up>
     351             :       && predicate<_Rel, _Tp, _Up> && predicate<_Rel, _Up, _Tp>;
     352             : 
     353             :   /// [concept.equiv], concept equivalence_relation
     354             :   template<typename _Rel, typename _Tp, typename _Up>
     355             :     concept equivalence_relation = relation<_Rel, _Tp, _Up>;
     356             : 
     357             :   /// [concept.strictweakorder], concept strict_weak_order
     358             :   template<typename _Rel, typename _Tp, typename _Up>
     359             :     concept strict_weak_order = relation<_Rel, _Tp, _Up>;
     360             : 
     361             : _GLIBCXX_END_NAMESPACE_VERSION
     362             : } // namespace
     363             : #endif // C++2a
     364             : 
     365             : #endif /* _GLIBCXX_CONCEPTS */

Generated by: LCOV version 1.14