File Coverage

/usr/local/lib/perl5/site_perl/5.26.1/XS/librangeV3.x/i/range/v3/utility/concepts.hpp
Criterion Covered Total %
statement 1 1 100.0
branch n/a
condition n/a
subroutine n/a
pod n/a
total 1 1 100.0


line stmt bran cond sub pod time code
1             /// \file
2             // Range v3 library
3             //
4             // Copyright Eric Niebler 2013-present
5             //
6             // Use, modification and distribution is subject to the
7             // Boost Software License, Version 1.0. (See accompanying
8             // file LICENSE_1_0.txt or copy at
9             // http://www.boost.org/LICENSE_1_0.txt)
10             //
11             // Acknowledgements: Thanks for Paul Fultz for the suggestions that
12             // concepts can be ordinary Boolean metafunctions.
13             //
14             // Project home: https://github.com/ericniebler/range-v3
15             //
16              
17             #ifndef RANGES_V3_UTILITY_CONCEPTS_HPP
18             #define RANGES_V3_UTILITY_CONCEPTS_HPP
19              
20             #include
21             #include
22             #include
23             #include
24             #include
25             #include
26             #include
27              
28             namespace ranges
29             {
30             inline namespace v3
31             {
32             /// \cond
33             namespace detail
34             {
35             constexpr struct void_tester
36             {
37             template
38             friend int operator,(T &&, void_tester);
39             } void_ {};
40              
41             constexpr struct is_void_t
42             {
43             int operator()(detail::void_tester) const;
44             } is_void {};
45              
46             constexpr struct valid_expr_t
47             {
48             template
49             void operator()(T &&...) const;
50             } valid_expr {};
51              
52             constexpr struct same_type_t
53             {
54             template
55             auto operator()(T &&, U &&) const ->
56             meta::if_, int>;
57             } same_type {};
58              
59             constexpr struct is_true_t
60             {
61             template
62             auto operator()(Bool_) const ->
63             meta::if_c;
64             } is_true {};
65              
66             constexpr struct is_false_t
67             {
68             template
69             auto operator()(Bool_) const ->
70             meta::if_c;
71             } is_false {};
72              
73             template
74             struct base_concept
75             {
76             using type = Concept;
77             };
78              
79             template
80             struct base_concept
81             {
82             using type = Concept;
83             };
84              
85             template
86             using base_concept_t = typename base_concept::type;
87              
88             template
89             struct base_concepts_of
90             {
91             using type = meta::list<>;
92             };
93              
94             template
95             struct base_concepts_of>
96             {
97             using type = typename Concept::base_concepts_t;
98             };
99              
100             template
101             using base_concepts_of_t = meta::_t>;
102              
103             template
104             auto models_(any) ->
105             std::false_type;
106              
107             #if (defined(__GNUC__) && !defined(__clang__) && __GNUC__ == 5 && __GNUC_MINOR__ < 5) || \
108             defined(RANGES_WORKAROUND_MSVC_701425)
109             template
110             T gcc_bugs_bugs_bugs(T);
111              
112             template
113             typename = decltype(gcc_bugs_bugs_bugs(&Concept::template requires_))>
114             #else
115             template
116             typename = decltype(&Concept::template requires_)>
117             #endif
118             auto models_(Concept *) ->
119             meta::apply<
120             meta::quote,
121             meta::transform<
122             base_concepts_of_t,
123             meta::bind_back, Ts...>>>;
124              
125             template
126             struct most_refined_
127             {};
128              
129             template
130             struct most_refined_>
131             {
132             using type = Head;
133 1276           constexpr operator Head*() const { return nullptr; }
134             constexpr Head* operator()() const { return nullptr; }
135             };
136             }
137             /// \endcond
138              
139             /// \addtogroup group-concepts
140             /// @{
141             ///
142             namespace concepts
143             {
144             using detail::void_;
145             using detail::is_void;
146             using detail::valid_expr;
147             using detail::same_type;
148             using detail::is_true;
149             using detail::is_false;
150             using ranges::uncvref_t;
151              
152             using _1 = std::integral_constant;
153             using _2 = std::integral_constant;
154             using _3 = std::integral_constant;
155             using _4 = std::integral_constant;
156             using _5 = std::integral_constant;
157             using _6 = std::integral_constant;
158             using _7 = std::integral_constant;
159             using _8 = std::integral_constant;
160             using _9 = std::integral_constant;
161              
162             template
163             Ret returns_(T const &);
164              
165             template
166             auto convertible_to(U && u) ->
167             decltype(concepts::returns_(static_cast((U &&) u)));
168              
169             template
170             auto has_type(U &&) ->
171             meta::if_, int>;
172              
173             ////////////////////////////////////////////////////////////////////////////////////////////
174             // refines
175             template
176             struct refines
177             : virtual detail::base_concept_t...
178             {
179             // So that we don't create these by accident, since it's surprisingly expensive to set
180             // up the vtable, given all the virtual bases.
181             refines() = delete;
182              
183             using base_concepts_t = meta::list;
184              
185             template
186             void requires_();
187             };
188              
189             ////////////////////////////////////////////////////////////////////////////////////////////
190             // models
191             template
192             struct models
193             : meta::bool_(_nullptr_v()))>::value>
194             {};
195              
196             template
197             struct models
198             : models, Args>...>
199             {};
200              
201             ////////////////////////////////////////////////////////////////////////////////////////////
202             // model_of
203             template
204             auto model_of(Ts &&...) ->
205             meta::if_c::value, int>;
206              
207             template
208             auto model_of() ->
209             meta::if_c::value, int>;
210              
211             ////////////////////////////////////////////////////////////////////////////////////////////
212             // most_refined
213             // Find the first concept in a list of concepts that is modeled by the Args
214             template
215             struct most_refined
216             : detail::most_refined_<
217             meta::find_if<
218             Concepts,
219             meta::bind_back, Ts...>>>
220             {};
221              
222             template
223             using most_refined_t = meta::_t>;
224              
225             ////////////////////////////////////////////////////////////////////////////////////////////
226             // Core language concepts
227             ////////////////////////////////////////////////////////////////////////////////////////////
228              
229             struct Satisfies
230             {
231             template
232             auto requires_() -> decltype(
233             concepts::valid_expr(
234             concepts::is_true(meta::invoke{})
235             ));
236             };
237              
238             struct Same
239             {
240             template
241             struct same : std::true_type {};
242             template
243             struct same : meta::and_c::value...> {};
244             template
245             using same_t = meta::_t>;
246              
247             template
248             auto requires_() -> decltype(
249             concepts::valid_expr(
250             concepts::is_true(same_t{})
251             ));
252             };
253              
254             /// \cond
255             struct ImplicitlyConvertibleTo
256             {
257             template
258             auto requires_() -> decltype(
259             concepts::valid_expr(
260             concepts::is_true(detail::is_convertible{})
261             ));
262             };
263              
264             struct ExplicitlyConvertibleTo
265             {
266             template
267             auto requires_(From (&from)()) -> decltype(
268             concepts::valid_expr(
269             ((void) static_cast(from()), 42)
270             ));
271             };
272             /// \endcond
273              
274             struct ConvertibleTo
275             : refines
276             {};
277              
278             struct DerivedFrom
279             {
280             template
281             auto requires_() -> decltype(
282             concepts::valid_expr(
283             concepts::is_true(std::is_base_of{}),
284             concepts::is_true(detail::is_convertible<
285             meta::_t> *, meta::_t> *>{})
286             ));
287             };
288              
289             struct CommonReference
290             {
291             template
292             using reference_t = common_reference_t;
293              
294             template
295             auto requires_() -> decltype(
296             concepts::valid_expr(
297             concepts::model_of, reference_t>(),
298             concepts::model_of>(),
299             concepts::model_of>()
300             ));
301              
302             template
303             typename CommonReference_ = CommonReference>
304             auto requires_() -> decltype(
305             concepts::valid_expr(
306             concepts::model_of(),
307             concepts::model_of, Rest...>()
308             ));
309             };
310              
311             struct Common
312             {
313             template
314             using value_t = common_type_t;
315              
316             template
317             auto requires_() -> decltype(
318             concepts::valid_expr(
319             concepts::is_true(std::is_same, uncvref_t>{})
320             ));
321              
322             template
323             auto requires_() -> decltype(
324             concepts::valid_expr(
325             concepts::is_false(std::is_same, uncvref_t>{}),
326             concepts::model_of, value_t>(),
327             concepts::model_of>(),
328             concepts::model_of>(),
329             concepts::model_of<
330             CommonReference, detail::as_cref_t, detail::as_cref_t>(),
331             concepts::model_of<
332             CommonReference,
333             value_t &,
334             common_reference_t, detail::as_cref_t>>()
335             ));
336              
337             template
338             typename Common_ = Common>
339             auto requires_() -> decltype(
340             concepts::valid_expr(
341             concepts::model_of(),
342             concepts::model_of, Rest...>()
343             ));
344             };
345              
346             struct Integral
347             {
348             template
349             auto requires_() -> decltype(
350             concepts::valid_expr(
351             concepts::is_true(std::is_integral{})
352             ));
353             };
354              
355             struct SignedIntegral
356             : refines
357             {
358             template
359             auto requires_() -> decltype(
360             concepts::valid_expr(
361             concepts::is_true(std::is_signed{})
362             ));
363             };
364              
365             struct UnsignedIntegral
366             : refines
367             {
368             template
369             auto requires_() -> decltype(
370             concepts::valid_expr(
371             concepts::is_false(std::is_signed{})
372             ));
373             };
374              
375             struct Assignable
376             {
377             template
378             auto requires_(T &&t, U &&u) -> decltype(
379             concepts::valid_expr(
380             concepts::is_true(std::is_lvalue_reference{}),
381             concepts::model_of<
382             CommonReference, detail::as_cref_t, detail::as_cref_t>(),
383             concepts::has_type((T &&) t = (U &&) u)
384             ));
385             };
386              
387             struct Swappable
388             {
389             template
390             auto requires_(T &&t) -> decltype(
391             concepts::valid_expr(
392             ((void)ranges::swap((T &&) t, (T &&) t), 42)
393             ));
394              
395             template
396             auto requires_(T && t, U && u) -> decltype(
397             concepts::valid_expr(
398             concepts::model_of(),
399             concepts::model_of(),
400             concepts::model_of<
401             CommonReference, detail::as_cref_t, detail::as_cref_t>(),
402             ((void)ranges::swap((T &&) t, (U &&) u), 42),
403             ((void)ranges::swap((U &&) u, (T &&) t), 42)
404             ));
405             };
406              
407             ////////////////////////////////////////////////////////////////////////////////////////////
408             // Comparison concepts
409             ////////////////////////////////////////////////////////////////////////////////////////////
410             struct WeaklyEqualityComparable
411             {
412             template
413             auto requires_(detail::as_cref_t t, detail::as_cref_t u) -> decltype(
414             // Not to spec: doesn't compare to a Boolean trait
415             concepts::valid_expr(
416             concepts::convertible_to(t == u),
417             concepts::convertible_to(t != u),
418             concepts::convertible_to(u == t),
419             concepts::convertible_to(u != t)
420             ));
421             };
422              
423             struct EqualityComparable
424             {
425             template
426             auto requires_(detail::as_cref_t t) -> decltype(
427             concepts::valid_expr(
428             concepts::convertible_to(t == t),
429             concepts::convertible_to(t != t)
430             ));
431              
432             template
433             auto requires_() -> decltype(
434             concepts::valid_expr(
435             concepts::is_true(std::is_same{}),
436             concepts::model_of()
437             ));
438              
439             // Cross-type equality comparison from N3351:
440             // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3351.pdf
441             template
442             typename C = common_reference_t, detail::as_cref_t>>
443             auto requires_() -> decltype(
444             concepts::valid_expr(
445             concepts::is_false(std::is_same{}),
446             concepts::model_of(),
447             concepts::model_of(),
448             concepts::model_of(),
449             concepts::model_of<
450             CommonReference, detail::as_cref_t, detail::as_cref_t>(),
451             concepts::model_of()
452             ));
453             };
454              
455             struct WeaklyOrdered
456             {
457             template
458             auto requires_(T && t) -> decltype(
459             concepts::valid_expr(
460             concepts::convertible_to(t < t),
461             concepts::convertible_to(t > t),
462             concepts::convertible_to(t <= t),
463             concepts::convertible_to(t >= t)
464             ));
465              
466             template
467             typename C = common_reference_t, detail::as_cref_t>>
468             auto requires_(detail::as_cref_t t, detail::as_cref_t u) -> decltype(
469             concepts::valid_expr(
470             concepts::model_of(),
471             concepts::model_of(),
472             concepts::model_of<
473             CommonReference, detail::as_cref_t, detail::as_cref_t>(),
474             concepts::model_of(),
475             concepts::convertible_to(t < u),
476             concepts::convertible_to(u < t),
477             concepts::convertible_to(t > u),
478             concepts::convertible_to(u > t),
479             concepts::convertible_to(t <= u),
480             concepts::convertible_to(u <= t),
481             concepts::convertible_to(t >= u),
482             concepts::convertible_to(u >= t)
483             ));
484             };
485              
486             struct TotallyOrdered
487             : refines
488             {
489             template
490             void requires_();
491              
492             template
493             auto requires_() -> decltype(
494             concepts::valid_expr(
495             concepts::model_of(),
496             concepts::model_of()
497             ));
498             };
499              
500             ////////////////////////////////////////////////////////////////////////////////////////////
501             // Object concepts
502             ////////////////////////////////////////////////////////////////////////////////////////////
503              
504             struct Destructible
505             {
506             template
507             auto requires_() -> decltype(
508             concepts::valid_expr(
509             concepts::is_true(std::is_nothrow_destructible())
510             ));
511             };
512              
513             struct Constructible
514             : refines
515             {
516             template
517             auto requires_() -> decltype(
518             concepts::valid_expr(
519             concepts::is_true(std::is_constructible{})
520             ));
521             };
522              
523             struct DefaultConstructible
524             : refines
525             {
526             template
527             void requires_();
528             };
529              
530             struct MoveConstructible
531             {
532             template
533             auto requires_() -> decltype(
534             concepts::valid_expr(
535             concepts::model_of(),
536             concepts::model_of()
537             ));
538             };
539              
540             struct CopyConstructible
541             : refines
542             {
543             template
544             auto requires_() -> decltype(
545             concepts::valid_expr(
546             concepts::model_of(),
547             concepts::model_of(),
548             concepts::model_of(),
549             concepts::model_of(),
550             concepts::model_of(),
551             concepts::model_of()
552             ));
553             };
554              
555             struct Movable
556             : refines
557             {
558             template
559             auto requires_() -> decltype(
560             concepts::valid_expr(
561             concepts::is_true(std::is_object{}),
562             concepts::model_of(),
563             concepts::model_of()
564             ));
565             };
566              
567             struct Copyable
568             : refines
569             {
570             template
571             auto requires_() -> decltype(
572             concepts::valid_expr(
573             // Spec requires this to be validated
574             concepts::model_of(),
575             // Spec does not require these to be validated
576             concepts::model_of(),
577             concepts::model_of()
578             ));
579             };
580              
581             struct SemiRegular
582             : refines
583             {
584             // Axiom: copies are independent. See Fundamentals of Generic Programming
585             // http://www.stepanovpapers.com/DeSt98.pdf
586             };
587              
588             struct Regular
589             : refines
590             {};
591             }
592              
593             template class Trait, typename ...Ts>
594             using Satisfies = concepts::models, Ts...>;
595              
596             template
597             using Same = concepts::Same::same_t; // This handles void better than using the Same concept
598              
599             template
600             using ImplicitlyConvertibleTo =
601             concepts::models;
602              
603             template
604             using ExplicitlyConvertibleTo =
605             concepts::models;
606              
607             template
608             using ConvertibleTo = concepts::models;
609              
610             template
611             using DerivedFrom = concepts::models;
612              
613             template
614             using CommonReference =
615             concepts::models;
616              
617             template
618             using Common =
619             concepts::models;
620              
621             template
622             using Integral = concepts::models;
623              
624             template
625             using SignedIntegral = concepts::models;
626              
627             template
628             using UnsignedIntegral = concepts::models;
629              
630             template
631             using Destructible = concepts::models;
632              
633             template
634             using Constructible = concepts::models;
635              
636             template
637             using DefaultConstructible = concepts::models;
638              
639             template
640             using MoveConstructible = concepts::models;
641              
642             template
643             using CopyConstructible = concepts::models;
644              
645             template
646             using Assignable = concepts::models;
647              
648             template
649             using Movable = concepts::models;
650              
651             template
652             using Copyable = concepts::models;
653              
654             template
655             using WeaklyEqualityComparable = concepts::models;
656              
657             template
658             using EqualityComparable = concepts::models;
659              
660             template
661             using WeaklyOrdered = concepts::models;
662              
663             template
664             using TotallyOrdered = concepts::models;
665              
666             template
667             using SemiRegular = concepts::models;
668              
669             template
670             using Regular = concepts::models;
671              
672             template
673             using Swappable = concepts::models;
674             }
675             }
676              
677             #define CONCEPT_PP_CAT_(X, Y) X ## Y
678             #define CONCEPT_PP_CAT(X, Y) CONCEPT_PP_CAT_(X, Y)
679              
680             /// \addtogroup group-concepts
681             /// @{
682             #define CONCEPT_REQUIRES_(...) \
683             bool CONCEPT_PP_CAT(_concept_requires_, __LINE__) = false, \
684             typename std::enable_if< \
685             CONCEPT_PP_CAT(_concept_requires_, __LINE__) || (__VA_ARGS__) \
686             >::type* = nullptr \
687             /**/
688              
689             #define CONCEPT_REQUIRES(...) template \
690             /**/
691              
692             #if RANGES_CXX_STATIC_ASSERT >= RANGES_CXX_STATIC_ASSERT_17
693             #define CONCEPT_ASSERT static_assert
694             #else
695             #define CONCEPT_ASSERT(...) static_assert((__VA_ARGS__), "Concept check failed: " #__VA_ARGS__)
696             #endif
697             /// @}
698              
699             #define CONCEPT_ASSERT_MSG static_assert
700             /// @}
701              
702             #endif // RANGES_V3_UTILITY_CONCEPTS_HPP