1// -*- C++ -*-
2// typelist for the C++ library testsuite.
3//
4// Copyright (C) 2005-2015 Free Software Foundation, Inc.
5//
6// This file is part of the GNU ISO C++ Library.  This library is free
7// software; you can redistribute it and/or modify it under the
8// terms of the GNU General Public License as published by the
9// Free Software Foundation; either version 3, or (at your option)
10// any later version.
11//
12// This library is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License along
18// with this library; see the file COPYING3.  If not see
19// <http://www.gnu.org/licenses/>.
20//
21
22#ifndef _TESTSUITE_COMMON_TYPES_H
23#define _TESTSUITE_COMMON_TYPES_H 1
24
25#include <ext/typelist.h>
26
27#include <ext/new_allocator.h>
28#include <ext/malloc_allocator.h>
29#include <ext/mt_allocator.h>
30#include <ext/bitmap_allocator.h>
31#include <ext/pool_allocator.h>
32
33#include <algorithm>
34
35#include <vector>
36#include <list>
37#include <deque>
38#include <string>
39#include <limits>
40
41#include <map>
42#include <set>
43#include <tr1/functional>
44#include <tr1/unordered_map>
45#include <tr1/unordered_set>
46
47#if __cplusplus >= 201103L
48#include <atomic>
49#include <type_traits>
50#endif
51
52namespace __gnu_test
53{
54  using __gnu_cxx::typelist::node;
55  using __gnu_cxx::typelist::transform;
56  using __gnu_cxx::typelist::append;
57
58  // All the allocators to test.
59  template<typename Tp, bool Thread>
60    struct allocator_policies
61    {
62      typedef Tp			    	value_type;
63      typedef __gnu_cxx::new_allocator<Tp> 		a1;
64      typedef __gnu_cxx::malloc_allocator<Tp> 		a2;
65      typedef __gnu_cxx::__common_pool_policy<__gnu_cxx::__pool, Thread> pool_policy;
66      typedef __gnu_cxx::__mt_alloc<Tp, pool_policy>	a3;
67      typedef __gnu_cxx::bitmap_allocator<Tp> 		a4;
68      typedef __gnu_cxx::__pool_alloc<Tp> 		a5;
69      typedef node<_GLIBCXX_TYPELIST_CHAIN5(a1, a2, a3, a4, a5)> type;
70    };
71
72  // Typelists for vector, string, list, deque.
73  // XXX should just use template templates
74  template<typename Tp, bool Thread>
75    struct vectors
76    {
77      typedef Tp			    		value_type;
78
79      template<typename Tl>
80        struct vector_shell
81	{
82	  typedef Tl 					allocator_type;
83	  typedef std::vector<value_type, allocator_type>	type;
84	};
85
86      typedef allocator_policies<value_type, Thread>	allocator_types;
87      typedef typename allocator_types::type 		allocator_typelist;
88      typedef typename transform<allocator_typelist, vector_shell>::type type;
89    };
90
91  template<typename Tp, bool Thread>
92    struct lists
93    {
94      typedef Tp			    		value_type;
95
96      template<typename Tl>
97        struct list_shell
98	{
99	  typedef Tl 					allocator_type;
100	  typedef std::list<value_type, allocator_type>	type;
101	};
102
103      typedef allocator_policies<value_type, Thread>	allocator_types;
104      typedef typename allocator_types::type 		allocator_typelist;
105      typedef typename transform<allocator_typelist, list_shell>::type type;
106    };
107
108  template<typename Tp, bool Thread>
109    struct deques
110    {
111      typedef Tp			    		value_type;
112
113      template<typename Tl>
114        struct deque_shell
115	{
116	  typedef Tl 					allocator_type;
117	  typedef std::deque<value_type, allocator_type>	type;
118	};
119
120      typedef allocator_policies<value_type, Thread>	allocator_types;
121      typedef typename allocator_types::type 		allocator_typelist;
122      typedef typename transform<allocator_typelist, deque_shell>::type type;
123    };
124
125  template<typename Tp, bool Thread>
126    struct strings
127    {
128      typedef Tp			    		value_type;
129
130      template<typename Tl>
131        struct string_shell
132	{
133	  typedef Tl 					allocator_type;
134	  typedef std::char_traits<value_type> 		traits_type;
135	  typedef std::basic_string<value_type, traits_type, allocator_type>	type;
136	};
137
138      typedef allocator_policies<value_type, Thread>	allocator_types;
139      typedef typename allocator_types::type 		allocator_typelist;
140      typedef typename transform<allocator_typelist, string_shell>::type type;
141    };
142
143  // A typelist of vector, list, deque, and string all instantiated
144  // with each of the allocator policies.
145  template<typename Tp, bool Thread>
146    struct sequence_containers
147    {
148      typedef Tp			    		value_type;
149
150      typedef typename vectors<value_type, Thread>::type vector_typelist;
151      typedef typename lists<value_type, Thread>::type   list_typelist;
152      typedef typename deques<value_type, Thread>::type  deque_typelist;
153      typedef typename strings<value_type, Thread>::type string_typelist;
154
155      typedef typename append<vector_typelist, list_typelist>::type a1;
156      typedef typename append<deque_typelist, string_typelist>::type a2;
157      typedef typename append<a1, a2>::type type;
158    };
159
160  // Typelists for map, set, unordered_set, unordered_map.
161  template<typename Tp, bool Thread>
162    struct maps
163    {
164      typedef Tp			    		value_type;
165      typedef Tp 					key_type;
166      typedef std::pair<const key_type, value_type> 	pair_type;
167      typedef std::less<key_type>      			compare_function;
168
169      template<typename Tl>
170        struct container
171	{
172	  typedef Tl 					allocator_type;
173	  typedef std::map<key_type, value_type, compare_function, allocator_type>	type;
174	};
175
176      typedef allocator_policies<pair_type, Thread>	allocator_types;
177      typedef typename allocator_types::type 		allocator_typelist;
178      typedef typename transform<allocator_typelist, container>::type type;
179    };
180
181  template<typename Tp, bool Thread>
182    struct unordered_maps
183    {
184      typedef Tp			    		value_type;
185      typedef Tp 					key_type;
186      typedef std::pair<const key_type, value_type> 	pair_type;
187      typedef std::tr1::hash<key_type>      		hash_function;
188      typedef std::equal_to<key_type>      		equality_function;
189
190      template<typename Tl>
191        struct container
192	{
193	  typedef Tl 					allocator_type;
194	  typedef std::tr1::unordered_map<key_type, value_type, hash_function, equality_function, allocator_type>	type;
195	};
196
197      typedef allocator_policies<pair_type, Thread>	allocator_types;
198      typedef typename allocator_types::type 		allocator_typelist;
199      typedef typename transform<allocator_typelist, container>::type type;
200    };
201
202  template<typename Tp, bool Thread>
203    struct sets
204    {
205      typedef Tp			    		value_type;
206      typedef Tp 					key_type;
207      typedef std::less<key_type>      			compare_function;
208
209      template<typename Tl>
210        struct container
211	{
212	  typedef Tl 					allocator_type;
213	  typedef std::set<key_type, compare_function, allocator_type>	type;
214	};
215
216      typedef allocator_policies<key_type, Thread>	allocator_types;
217      typedef typename allocator_types::type 		allocator_typelist;
218      typedef typename transform<allocator_typelist, container>::type type;
219    };
220
221  template<typename Tp, bool Thread>
222    struct unordered_sets
223    {
224      typedef Tp			    		value_type;
225      typedef Tp 					key_type;
226      typedef std::tr1::hash<key_type>      		hash_function;
227      typedef std::equal_to<key_type>      		equality_function;
228
229      template<typename Tl>
230        struct container
231	{
232	  typedef Tl 					allocator_type;
233	  typedef std::tr1::unordered_set<key_type, hash_function, equality_function, allocator_type>	type;
234	};
235
236      typedef allocator_policies<key_type, Thread>	allocator_types;
237      typedef typename allocator_types::type 		allocator_typelist;
238      typedef typename transform<allocator_typelist, container>::type type;
239    };
240
241
242  // A typelist  of all associated  container types, with each  of the
243  // allocator policies.
244  template<typename Tp, bool Thread>
245    struct associative_containers
246    {
247      typedef Tp			    		value_type;
248
249      typedef typename maps<value_type, Thread>::type map_typelist;
250      typedef typename sets<value_type, Thread>::type set_typelist;
251      typedef typename unordered_maps<value_type, Thread>::type unordered_map_typelist;
252      typedef typename unordered_sets<value_type, Thread>::type unordered_set_typelist;
253
254      typedef typename append<map_typelist, unordered_map_typelist>::type a1;
255      typedef typename append<set_typelist, unordered_set_typelist>::type a2;
256      typedef typename append<a1, a2>::type type;
257    };
258
259  // A typelist of all standard integral types.
260  struct integral_types
261  {
262    typedef bool 		a1;
263    typedef char 		a2;
264    typedef signed char 	a3;
265    typedef unsigned char 	a4;
266    typedef short 		a5;
267    typedef unsigned short 	a6;
268    typedef int 		a7;
269    typedef unsigned int 	a8;
270    typedef long 		a9;
271    typedef unsigned long 	a10;
272    typedef long long 		a11;
273    typedef unsigned long long 	a12;
274    typedef wchar_t 		a13;
275#if __cplusplus >= 201103L
276    typedef char16_t 		a14;
277    typedef char32_t 		a15;
278
279    typedef node<_GLIBCXX_TYPELIST_CHAIN15(a1, a2, a3, a4, a5, a6, a7, a8, a9,
280					   a10, a11, a12, a13, a14, a15)> type;
281#else
282    typedef node<_GLIBCXX_TYPELIST_CHAIN13(a1, a2, a3, a4, a5, a6, a7, a8, a9,
283					   a10, a11, a12, a13)> type;
284#endif
285  };
286
287  // A typelist of all standard integral types + the GNU 128-bit types.
288  struct integral_types_gnu
289  {
290    typedef bool 		a1;
291    typedef char 		a2;
292    typedef signed char 	a3;
293    typedef unsigned char 	a4;
294    typedef short 		a5;
295    typedef unsigned short 	a6;
296    typedef int 		a7;
297    typedef unsigned int 	a8;
298    typedef long 		a9;
299    typedef unsigned long 	a10;
300    typedef long long 		a11;
301    typedef unsigned long long 	a12;
302    typedef wchar_t 		a13;
303#if __cplusplus >= 201103L
304    typedef char16_t 		a14;
305    typedef char32_t 		a15;
306# if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128)
307    typedef __int128            a16;
308    typedef unsigned __int128   a17;
309
310    typedef node<_GLIBCXX_TYPELIST_CHAIN17(a1, a2, a3, a4, a5, a6, a7, a8, a9,
311					   a10, a11, a12, a13, a14, a15,
312					   a16, a17)> type;
313# else
314    typedef node<_GLIBCXX_TYPELIST_CHAIN15(a1, a2, a3, a4, a5, a6, a7, a8, a9,
315					   a10, a11, a12, a13, a14, a15)> type;
316# endif
317#else
318# if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128)
319    typedef __int128            a14;
320    typedef unsigned __int128   a15;
321
322    typedef node<_GLIBCXX_TYPELIST_CHAIN15(a1, a2, a3, a4, a5, a6, a7, a8, a9,
323					   a10, a11, a12, a13, a14, a15)> type;
324# else
325   typedef node<_GLIBCXX_TYPELIST_CHAIN13(a1, a2, a3, a4, a5, a6, a7, a8, a9,
326					  a10, a11, a12, a13)> type;
327# endif
328#endif
329  };
330
331#if __cplusplus >= 201103L
332  struct atomic_integrals_no_bool
333  {
334    typedef std::atomic_char        	a2;
335    typedef std::atomic_schar 		a3;
336    typedef std::atomic_uchar 		a4;
337    typedef std::atomic_short       	a5;
338    typedef std::atomic_ushort 		a6;
339    typedef std::atomic_int 		a7;
340    typedef std::atomic_uint 		a8;
341    typedef std::atomic_long        	a9;
342    typedef std::atomic_ulong 		a10;
343    typedef std::atomic_llong       	a11;
344    typedef std::atomic_ullong 		a12;
345    typedef std::atomic_wchar_t     	a13;
346    typedef std::atomic_char16_t    	a14;
347    typedef std::atomic_char32_t    	a15;
348
349    typedef node<_GLIBCXX_TYPELIST_CHAIN14(a2, a3, a4, a5, a6, a7, a8, a9,
350					   a10, a11, a12, a13, a14, a15)> type;
351  };
352
353  struct atomic_integrals
354  {
355    typedef std::atomic_bool        	a1;
356    typedef std::atomic_char        	a2;
357    typedef std::atomic_schar 		a3;
358    typedef std::atomic_uchar 		a4;
359    typedef std::atomic_short       	a5;
360    typedef std::atomic_ushort 		a6;
361    typedef std::atomic_int 		a7;
362    typedef std::atomic_uint 		a8;
363    typedef std::atomic_long        	a9;
364    typedef std::atomic_ulong 		a10;
365    typedef std::atomic_llong       	a11;
366    typedef std::atomic_ullong 		a12;
367    typedef std::atomic_wchar_t     	a13;
368    typedef std::atomic_char16_t    	a14;
369    typedef std::atomic_char32_t    	a15;
370
371    typedef node<_GLIBCXX_TYPELIST_CHAIN15(a1, a2, a3, a4, a5, a6, a7, a8, a9,
372					   a10, a11, a12, a13, a14, a15)> type;
373  };
374
375
376  template<typename Tp>
377    struct atomics
378    {
379      typedef Tp			value_type;
380      typedef std::atomic<value_type>	type;
381    };
382
383  typedef transform<integral_types::type, atomics>::type atomics_tl;
384#endif
385
386  template<typename Tp>
387    struct numeric_limits
388    {
389      typedef Tp			value_type;
390      typedef std::numeric_limits<value_type>	type;
391    };
392
393  typedef transform<integral_types_gnu::type, numeric_limits>::type limits_tl;
394
395  struct has_increment_operators
396  {
397    template<typename _Tp>
398      void
399      operator()()
400      {
401	struct _Concept
402	{
403	  void __constraint()
404	  {
405	    _Tp a;
406	    ++a; // prefix
407	    a++; // postfix
408	    a += a;
409	  }
410	};
411
412	void (_Concept::*__x)() __attribute__((unused))
413	  = &_Concept::__constraint;
414      }
415  };
416
417  struct has_decrement_operators
418  {
419    template<typename _Tp>
420      void
421      operator()()
422      {
423	struct _Concept
424	{
425	  void __constraint()
426	  {
427	    _Tp a;
428	    --a; // prefix
429	    a--; // postfix
430	    a -= a;
431	  }
432	};
433
434	void (_Concept::*__x)() __attribute__((unused))
435	  = &_Concept::__constraint;
436      }
437  };
438
439#if __cplusplus >= 201103L
440  template<typename _Tp>
441    void
442    constexpr_bitwise_operators()
443    {
444      constexpr _Tp a = _Tp();
445      constexpr _Tp b = _Tp();
446      constexpr _Tp c1 __attribute__((unused)) = a | b;
447      constexpr _Tp c2 __attribute__((unused)) = a & b;
448      constexpr _Tp c3 __attribute__((unused)) = a ^ b;
449      constexpr _Tp c4 __attribute__((unused)) = ~b;
450    }
451#endif
452
453  template<typename _Tp>
454    void
455    bitwise_operators()
456    {
457      _Tp a = _Tp();
458      _Tp b = _Tp();
459      a | b;
460      a & b;
461      a ^ b;
462      ~b;
463    }
464
465  template<typename _Tp>
466    void
467    bitwise_assignment_operators()
468    {
469      _Tp a = _Tp();
470      _Tp b = _Tp();
471      a |= b; // set
472      a &= ~b; // clear
473      a ^= b;
474    }
475
476  // 17.3.2.1.2 - Bitmask types [lib.bitmask.types]
477  // bitmask_operators
478  template<typename _BitmTp>
479    void
480    bitmask_operators()
481    {
482      bitwise_operators<_BitmTp>();
483      bitwise_assignment_operators<_BitmTp>();
484    }
485
486  struct has_bitwise_operators
487  {
488    template<typename _Tp>
489      void
490      operator()()
491      {
492	struct _Concept
493	{
494	  void __constraint()
495	  {
496	    a |= b; // set
497	    a &= ~b; // clear
498	    a ^= b;
499	  }
500	  _Tp a;
501	  _Tp b;
502	};
503
504	void (_Concept::*__x)() __attribute__((unused))
505	  = &_Concept::__constraint;
506      }
507  };
508
509#if __cplusplus >= 201103L
510
511  struct constexpr_comparison_eq_ne
512  {
513    template<typename _Tp1, typename _Tp2 = _Tp1>
514      void
515      operator()()
516      {
517	static_assert(_Tp1() == _Tp2(), "eq");
518	static_assert(!(_Tp1() != _Tp2()), "ne");
519      }
520  };
521
522  struct constexpr_comparison_operators
523  {
524    template<typename _Tp>
525      void
526      operator()()
527      {
528	static_assert(!(_Tp() < _Tp()), "less");
529	static_assert(_Tp() <= _Tp(), "leq");
530	static_assert(!(_Tp() > _Tp()), "more");
531	static_assert(_Tp() >= _Tp(), "meq");
532	static_assert(_Tp() == _Tp(), "eq");
533	static_assert(!(_Tp() != _Tp()), "ne");
534      }
535  };
536
537  // Generator to test standard layout
538  struct has_trivial_cons_dtor
539  {
540    template<typename _Tp>
541      void
542      operator()()
543      {
544	struct _Concept
545	{
546	  void __constraint()
547	  {
548	    typedef std::is_trivially_default_constructible<_Tp> ctor_p;
549	    static_assert(ctor_p::value, "default constructor not trivial");
550
551	    typedef std::is_trivially_destructible<_Tp> dtor_p;
552	    static_assert(dtor_p::value, "destructor not trivial");
553	  }
554	};
555
556	void (_Concept::*__x)() __attribute__((unused))
557	  = &_Concept::__constraint;
558      }
559  };
560
561  struct standard_layout
562  {
563    template<typename _Tp>
564      void
565      operator()()
566      {
567	struct _Concept
568	{
569	  void __constraint()
570	  {
571	    typedef std::is_standard_layout<_Tp> standard_layout_p;
572	    static_assert(standard_layout_p::value, "not standard_layout");
573	  }
574	};
575
576	void (_Concept::*__x)() __attribute__((unused))
577	  = &_Concept::__constraint;
578      }
579  };
580#endif
581
582  // Generator to test base class
583  struct has_required_base_class
584  {
585    template<typename _TBase, typename _TDerived>
586      void
587      operator()()
588      {
589	struct _Concept
590	{
591	  void __constraint()
592	  {
593	    const _TDerived& obj = __a;
594	    const _TBase* base __attribute__((unused)) = &obj;
595	  }
596
597	  _TDerived __a;
598	};
599
600	void (_Concept::*__x)() __attribute__((unused))
601	  = &_Concept::__constraint;
602      }
603  };
604
605  // Generator to test assignment operator.
606  struct assignable
607  {
608    template<typename _Tp>
609      void
610      operator()()
611      {
612	struct _Concept
613	{
614	  void __constraint()
615	  { __v1 = __v2; }
616
617	  _Tp __v1;
618	  _Tp __v2;
619	};
620
621	void (_Concept::*__x)() __attribute__((unused))
622	  = &_Concept::__constraint;
623      }
624  };
625
626  // Generator to test default constructor.
627  struct default_constructible
628  {
629    template<typename _Tp>
630      void
631      operator()()
632      {
633	struct _Concept
634	{
635	  void __constraint()
636	  { _Tp __v __attribute__((unused)); }
637	};
638
639	void (_Concept::*__x)() __attribute__((unused))
640	  = &_Concept::__constraint;
641      }
642  };
643
644  // Generator to test copy constructor.
645  struct copy_constructible
646  {
647    template<typename _Tp>
648      void
649      operator()()
650      {
651	struct _Concept
652	{
653	  void __constraint()
654	  { _Tp __v2(__v1); }
655
656	  _Tp __v1;
657	};
658
659	void (_Concept::*__x)() __attribute__((unused))
660	  = &_Concept::__constraint;
661      }
662  };
663
664  // Generator to test direct initialization, single value constructor.
665  struct single_value_constructible
666  {
667    template<typename _Ttype, typename _Tvalue>
668      void
669      operator()()
670      {
671	struct _Concept
672	{
673	  void __constraint()
674	  { _Ttype __v(__a); }
675
676	  _Tvalue __a;
677	};
678
679	void (_Concept::*__x)() __attribute__((unused))
680	  = &_Concept::__constraint;
681      }
682  };
683
684#if __cplusplus >= 201103L
685  // Generator to test default constructor.
686  struct constexpr_default_constructible
687  {
688    template<typename _Tp, bool _IsLitp = std::is_literal_type<_Tp>::value>
689      struct _Concept;
690
691    // NB: _Tp must be a literal type.
692    // Have to have user-defined default ctor for this to work,
693    // or implicit default ctor must initialize all members.
694    template<typename _Tp>
695      struct _Concept<_Tp, true>
696      {
697	void __constraint()
698	{ constexpr _Tp __obj; }
699      };
700
701    // Non-literal type, declare local static and verify no
702    // constructors generated for _Tp within the translation unit.
703    template<typename _Tp>
704      struct _Concept<_Tp, false>
705      {
706	void __constraint()
707	{ static _Tp __obj; }
708      };
709
710    template<typename _Tp>
711      void
712      operator()()
713      {
714	_Concept<_Tp> c;
715	c.__constraint();
716      }
717  };
718
719  // Generator to test defaulted default constructor.
720  struct constexpr_defaulted_default_constructible
721  {
722    template<typename _Tp>
723      void
724      operator()()
725      {
726	struct _Concept
727	{
728	  void __constraint()
729	  { constexpr _Tp __v __attribute__((unused)) { }; }
730	};
731
732	void (_Concept::*__x)() __attribute__((unused))
733	  = &_Concept::__constraint;
734      }
735  };
736
737  struct constexpr_single_value_constructible
738  {
739    template<typename _Ttesttype, typename _Tvaluetype,
740	     bool _IsLitp = std::is_literal_type<_Ttesttype>::value>
741      struct _Concept;
742
743    // NB: _Tvaluetype and _Ttesttype must be literal types.
744    // Additional constraint on _Tvaluetype needed.  Either assume
745    // user-defined default ctor as per
746    // constexpr_default_constructible and provide no initializer,
747    // provide an initializer, or assume empty-list init-able. Choose
748    // the latter.
749    template<typename _Ttesttype, typename _Tvaluetype>
750      struct _Concept<_Ttesttype, _Tvaluetype, true>
751      {
752	void __constraint()
753	{
754	  constexpr _Tvaluetype __v { };
755	  constexpr _Ttesttype __obj(__v);
756	}
757      };
758
759    template<typename _Ttesttype, typename _Tvaluetype>
760      struct _Concept<_Ttesttype, _Tvaluetype, false>
761      {
762	void __constraint()
763	{
764	  const _Tvaluetype __v { };
765	  static _Ttesttype __obj(__v);
766	}
767      };
768
769    template<typename _Ttesttype, typename _Tvaluetype>
770      void
771      operator()()
772      {
773	_Concept<_Ttesttype, _Tvaluetype> c;
774	c.__constraint();
775      }
776  };
777#endif
778
779  // Generator to test direct list initialization
780#if __cplusplus >= 201103L
781  struct direct_list_initializable
782  {
783    template<typename _Ttype, typename _Tvalue>
784      void
785      operator()()
786      {
787	struct _Concept
788	{
789	  void __constraint()
790	  {
791	    _Ttype __v1 { }; // default ctor
792	    _Ttype __v2 { __a };  // single-argument ctor
793	  }
794
795	  _Tvalue __a;
796	};
797
798	void (_Concept::*__x)() __attribute__((unused))
799	  = &_Concept::__constraint;
800      }
801  };
802#endif
803
804  // Generator to test copy list initialization, aggregate initialization
805  struct copy_list_initializable
806  {
807    template<typename _Ttype, typename _Tvalue>
808      void
809      operator()()
810      {
811	struct _Concept
812	{
813	  void __constraint()
814	  { _Ttype __v __attribute__((unused)) = {__a}; }
815
816	  _Tvalue __a;
817	};
818
819	void (_Concept::*__x)() __attribute__((unused))
820	  = &_Concept::__constraint;
821      }
822  };
823
824  // Generator to test integral conversion operator
825  struct integral_convertable
826  {
827    template<typename _Ttype, typename _Tvalue>
828      void
829      operator()()
830      {
831	struct _Concept
832	{
833	  void __constraint()
834	  {
835	    _Tvalue __v0(0);
836	    _Tvalue __v1(1);
837	    _Ttype __a(__v1);
838	    __v0 = __a;
839
840	    bool test __attribute__((unused)) = true;
841	    VERIFY( __v1 == __v0 );
842	  }
843	};
844
845	void (_Concept::*__x)() __attribute__((unused))
846	  = &_Concept::__constraint;
847      }
848  };
849
850  // Generator to test integral assignment operator
851  struct integral_assignable
852  {
853    template<typename _Ttype, typename _Tvalue>
854      void
855      operator()()
856      {
857	struct _Concept
858	{
859	  void __constraint()
860	  {
861	    _Tvalue __v0(0);
862	    _Tvalue __v1(1);
863	    _Ttype __a(__v0);
864	    __a = __v1;
865	    _Tvalue __vr = __a;
866
867	    bool test __attribute__((unused)) = true;
868	    VERIFY( __v1 == __vr );
869	  }
870	};
871
872	void (_Concept::*__x)() __attribute__((unused))
873	  = &_Concept::__constraint;
874      }
875  };
876
877#if __cplusplus >= 201103L
878  // Generator to test lowering requirements for compare-and-exchange.
879  template<std::memory_order _Torder>
880  struct compare_exchange_order_lowering
881  {
882    template<typename _Tp>
883      void
884      operator()()
885      {
886        std::atomic<_Tp> __x;
887        _Tp __expected = 0;
888        __x.compare_exchange_strong(__expected, 1, _Torder);
889        __x.compare_exchange_weak(__expected, 1, _Torder);
890      }
891  };
892#endif
893} // namespace __gnu_test
894#endif
895