Skip to content

Commit 123a0d7

Browse files
authored
Fix compilation with avr-gcc 7x
1 parent 844ed14 commit 123a0d7

File tree

2 files changed

+359
-0
lines changed

2 files changed

+359
-0
lines changed

include/type_traits

+299
Original file line numberDiff line numberDiff line change
@@ -896,11 +896,257 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
896896
"template argument must be a complete class or an unbounded array");
897897
};
898898

899+
#if __GNUC__ >= 8
899900
template<typename _Tp, typename... _Args>
900901
struct __is_constructible_impl
901902
: public __bool_constant<__is_constructible(_Tp, _Args...)>
903+
{ };
904+
#else
905+
// Implementation of __is_constructible_impl.
906+
907+
struct __do_is_default_constructible_impl
908+
{
909+
template<typename _Tp, typename = decltype(_Tp())>
910+
static true_type __test(int);
911+
912+
template<typename>
913+
static false_type __test(...);
914+
};
915+
916+
template<typename _Tp>
917+
struct __is_default_constructible_impl
918+
: public __do_is_default_constructible_impl
919+
{
920+
typedef decltype(__test<_Tp>(0)) type;
921+
};
922+
923+
template<typename _Tp>
924+
struct __is_default_constructible_atom
925+
: public __and_<__not_<is_void<_Tp>>,
926+
__is_default_constructible_impl<_Tp>>::type
927+
{ };
928+
929+
template<typename _Tp, bool = is_array<_Tp>::value>
930+
struct __is_default_constructible_safe;
931+
932+
// The following technique is a workaround for a current core language
933+
// restriction, which does not allow for array types to occur in
934+
// functional casts of the form T(). Complete arrays can be default-
935+
// constructed, if the element type is default-constructible, but
936+
// arrays with unknown bounds are not.
937+
template<typename _Tp>
938+
struct __is_default_constructible_safe<_Tp, true>
939+
: public __and_<__is_array_known_bounds<_Tp>,
940+
__is_default_constructible_atom<typename
941+
remove_all_extents<_Tp>::type>>::type
942+
{ };
943+
944+
template<typename _Tp>
945+
struct __is_default_constructible_safe<_Tp, false>
946+
: public __is_default_constructible_atom<_Tp>::type
947+
{ };
948+
949+
// The hardest part of this trait is the binary direct-initialization
950+
// case, because we hit into a functional cast of the form T(arg).
951+
// This implementation uses different strategies depending on the
952+
// target type to reduce the test overhead as much as possible:
953+
//
954+
// a) For a reference target type, we use a static_cast expression
955+
// modulo its extra cases.
956+
//
957+
// b) For a non-reference target type we use a ::new expression.
958+
struct __do_is_static_castable_impl
959+
{
960+
template<typename _From, typename _To, typename
961+
= decltype(static_cast<_To>(declval<_From>()))>
962+
static true_type __test(int);
963+
964+
template<typename, typename>
965+
static false_type __test(...);
966+
};
967+
968+
template<typename _From, typename _To>
969+
struct __is_static_castable_impl
970+
: public __do_is_static_castable_impl
971+
{
972+
typedef decltype(__test<_From, _To>(0)) type;
973+
};
974+
975+
template<typename _From, typename _To>
976+
struct __is_static_castable_safe
977+
: public __is_static_castable_impl<_From, _To>::type
978+
{ };
979+
980+
// __is_static_castable
981+
template<typename _From, typename _To>
982+
struct __is_static_castable
983+
: public integral_constant<bool, (__is_static_castable_safe<
984+
_From, _To>::value)>
985+
{ };
986+
987+
// Implementation for non-reference types. To meet the proper
988+
// variable definition semantics, we also need to test for
989+
// is_destructible in this case.
990+
// This form should be simplified by a single expression:
991+
// ::delete ::new _Tp(declval<_Arg>()), see c++/51222.
992+
struct __do_is_direct_constructible_impl
993+
{
994+
template<typename _Tp, typename _Arg, typename
995+
= decltype(::new _Tp(declval<_Arg>()))>
996+
static true_type __test(int);
997+
998+
template<typename, typename>
999+
static false_type __test(...);
1000+
};
1001+
1002+
template<typename _Tp, typename _Arg>
1003+
struct __is_direct_constructible_impl
1004+
: public __do_is_direct_constructible_impl
1005+
{
1006+
typedef decltype(__test<_Tp, _Arg>(0)) type;
1007+
};
1008+
1009+
template<typename _Tp, typename _Arg>
1010+
struct __is_direct_constructible_new_safe
1011+
: public __and_<is_destructible<_Tp>,
1012+
__is_direct_constructible_impl<_Tp, _Arg>>
1013+
{ };
1014+
1015+
template<typename, typename>
1016+
struct is_same;
1017+
1018+
template<typename, typename>
1019+
struct is_base_of;
1020+
1021+
template<typename>
1022+
struct remove_reference;
1023+
1024+
template<typename _From, typename _To, bool
1025+
= __not_<__or_<is_void<_From>,
1026+
is_function<_From>>>::value>
1027+
struct __is_base_to_derived_ref;
1028+
1029+
template<typename _Tp, typename... _Args>
1030+
struct is_constructible;
1031+
1032+
// Detect whether we have a downcast situation during
1033+
// reference binding.
1034+
template<typename _From, typename _To>
1035+
struct __is_base_to_derived_ref<_From, _To, true>
1036+
{
1037+
typedef typename remove_cv<typename remove_reference<_From
1038+
>::type>::type __src_t;
1039+
typedef typename remove_cv<typename remove_reference<_To
1040+
>::type>::type __dst_t;
1041+
typedef __and_<__not_<is_same<__src_t, __dst_t>>,
1042+
is_base_of<__src_t, __dst_t>,
1043+
__not_<is_constructible<__dst_t, _From>>> type;
1044+
static constexpr bool value = type::value;
1045+
};
1046+
1047+
template<typename _From, typename _To>
1048+
struct __is_base_to_derived_ref<_From, _To, false>
1049+
: public false_type
1050+
{ };
1051+
1052+
template<typename _From, typename _To, bool
1053+
= __and_<is_lvalue_reference<_From>,
1054+
is_rvalue_reference<_To>>::value>
1055+
struct __is_lvalue_to_rvalue_ref;
1056+
1057+
// Detect whether we have an lvalue of non-function type
1058+
// bound to a reference-compatible rvalue-reference.
1059+
template<typename _From, typename _To>
1060+
struct __is_lvalue_to_rvalue_ref<_From, _To, true>
1061+
{
1062+
typedef typename remove_cv<typename remove_reference<
1063+
_From>::type>::type __src_t;
1064+
typedef typename remove_cv<typename remove_reference<
1065+
_To>::type>::type __dst_t;
1066+
typedef __and_<__not_<is_function<__src_t>>,
1067+
__or_<is_same<__src_t, __dst_t>,
1068+
is_base_of<__dst_t, __src_t>>> type;
1069+
static constexpr bool value = type::value;
1070+
};
1071+
1072+
template<typename _From, typename _To>
1073+
struct __is_lvalue_to_rvalue_ref<_From, _To, false>
1074+
: public false_type
1075+
{ };
1076+
1077+
// Here we handle direct-initialization to a reference type as
1078+
// equivalent to a static_cast modulo overshooting conversions.
1079+
// These are restricted to the following conversions:
1080+
// a) A base class value to a derived class reference
1081+
// b) An lvalue to an rvalue-reference of reference-compatible
1082+
// types that are not functions
1083+
template<typename _Tp, typename _Arg>
1084+
struct __is_direct_constructible_ref_cast
1085+
: public __and_<__is_static_castable<_Arg, _Tp>,
1086+
__not_<__or_<__is_base_to_derived_ref<_Arg, _Tp>,
1087+
__is_lvalue_to_rvalue_ref<_Arg, _Tp>
1088+
>>>
1089+
{ };
1090+
1091+
template<typename _Tp, typename _Arg>
1092+
struct __is_direct_constructible_new
1093+
: public conditional<is_reference<_Tp>::value,
1094+
__is_direct_constructible_ref_cast<_Tp, _Arg>,
1095+
__is_direct_constructible_new_safe<_Tp, _Arg>
1096+
>::type
1097+
{ };
1098+
1099+
template<typename _Tp, typename _Arg>
1100+
struct __is_direct_constructible
1101+
: public __is_direct_constructible_new<_Tp, _Arg>::type
1102+
{ };
1103+
1104+
// Since default-construction and binary direct-initialization have
1105+
// been handled separately, the implementation of the remaining
1106+
// n-ary construction cases is rather straightforward. We can use
1107+
// here a functional cast, because array types are excluded anyway
1108+
// and this form is never interpreted as a C cast.
1109+
struct __do_is_nary_constructible_impl
1110+
{
1111+
template<typename _Tp, typename... _Args, typename
1112+
= decltype(_Tp(declval<_Args>()...))>
1113+
static true_type __test(int);
1114+
1115+
template<typename, typename...>
1116+
static false_type __test(...);
1117+
};
1118+
1119+
template<typename _Tp, typename... _Args>
1120+
struct __is_nary_constructible_impl
1121+
: public __do_is_nary_constructible_impl
1122+
{
1123+
typedef decltype(__test<_Tp, _Args...>(0)) type;
1124+
};
1125+
1126+
template<typename _Tp, typename... _Args>
1127+
struct __is_nary_constructible
1128+
: public __is_nary_constructible_impl<_Tp, _Args...>::type
1129+
{
1130+
static_assert(sizeof...(_Args) > 1,
1131+
"Only useful for > 1 arguments");
1132+
};
1133+
1134+
template<typename _Tp, typename... _Args>
1135+
struct __is_constructible_impl
1136+
: public __is_nary_constructible<_Tp, _Args...>
9021137
{ };
9031138

1139+
template<typename _Tp, typename _Arg>
1140+
struct __is_constructible_impl<_Tp, _Arg>
1141+
: public __is_direct_constructible<_Tp, _Arg>
1142+
{ };
1143+
1144+
template<typename _Tp>
1145+
struct __is_constructible_impl<_Tp>
1146+
: public __is_default_constructible_safe<_Tp>::type
1147+
{ };
1148+
#endif
1149+
9041150
/// is_constructible
9051151
template<typename _Tp, typename... _Args>
9061152
struct is_constructible
@@ -998,10 +1244,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
9981244
{ };
9991245
#endif
10001246

1247+
#if __GNUC__ >= 8
10011248
template<typename _Tp, typename... _Args>
10021249
using __is_nothrow_constructible_impl
10031250
= __is_nt_constructible_impl<__is_constructible(_Tp, _Args...),
10041251
_Tp, _Args...>;
1252+
#else
1253+
template<typename _Tp, typename... _Args>
1254+
using __is_nothrow_constructible_impl
1255+
= __is_nt_constructible_impl<__is_constructible_impl<_Tp, _Args...>::value,
1256+
_Tp, _Args...>;
1257+
#endif
10051258

10061259
/// is_nothrow_constructible
10071260
template<typename _Tp, typename... _Args>
@@ -1064,6 +1317,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
10641317
"template argument must be a complete class or an unbounded array");
10651318
};
10661319

1320+
#if __GNUC__ >= 8
10671321
/// is_assignable
10681322
template<typename _Tp, typename _Up>
10691323
struct is_assignable
@@ -1072,6 +1326,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
10721326
static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
10731327
"template argument must be a complete class or an unbounded array");
10741328
};
1329+
#else
1330+
template<typename _Tp, typename _Up>
1331+
class __is_assignable_helper
1332+
{
1333+
template<typename _Tp1, typename _Up1,
1334+
typename = decltype(declval<_Tp1>() = declval<_Up1>())>
1335+
static true_type
1336+
__test(int);
1337+
1338+
template<typename, typename>
1339+
static false_type
1340+
__test(...);
1341+
1342+
public:
1343+
typedef decltype(__test<_Tp, _Up>(0)) type;
1344+
};
1345+
1346+
/// is_assignable
1347+
template<typename _Tp, typename _Up>
1348+
struct is_assignable
1349+
: public __is_assignable_helper<_Tp, _Up>::type
1350+
{ };
1351+
#endif
10751352

10761353
template<typename _Tp, bool = __is_referenceable<_Tp>::value>
10771354
struct __is_copy_assignable_impl;
@@ -1080,10 +1357,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
10801357
struct __is_copy_assignable_impl<_Tp, false>
10811358
: public false_type { };
10821359

1360+
#if __GNUC__ >= 8
10831361
template<typename _Tp>
10841362
struct __is_copy_assignable_impl<_Tp, true>
10851363
: public __bool_constant<__is_assignable(_Tp&, const _Tp&)>
10861364
{ };
1365+
#else
1366+
template<typename _Tp>
1367+
struct __is_copy_assignable_impl<_Tp, true>
1368+
: public is_assignable<_Tp&, const _Tp&>
1369+
{ };
1370+
#endif
10871371

10881372
/// is_copy_assignable
10891373
template<typename _Tp>
@@ -1101,10 +1385,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
11011385
struct __is_move_assignable_impl<_Tp, false>
11021386
: public false_type { };
11031387

1388+
#if __GNUC__ >= 8
11041389
template<typename _Tp>
11051390
struct __is_move_assignable_impl<_Tp, true>
11061391
: public __bool_constant<__is_assignable(_Tp&, _Tp&&)>
11071392
{ };
1393+
#else
1394+
template<typename _Tp>
1395+
struct __is_move_assignable_impl<_Tp, true>
1396+
: public is_assignable<_Tp&, _Tp&&>
1397+
{ };
1398+
#endif
11081399

11091400
/// is_move_assignable
11101401
template<typename _Tp>
@@ -1120,11 +1411,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
11201411
: public integral_constant<bool, noexcept(declval<_Tp>() = declval<_Up>())>
11211412
{ };
11221413

1414+
#if __GNUC__ >= 8
11231415
template<typename _Tp, typename _Up>
11241416
struct __is_nothrow_assignable_impl
11251417
: public __and_<__bool_constant<__is_assignable(_Tp, _Up)>,
11261418
__is_nt_assignable_impl<_Tp, _Up>>
11271419
{ };
1420+
#else
1421+
template<typename _Tp, typename _Up>
1422+
struct __is_nothrow_assignable_impl
1423+
: public __and_<is_assignable<_Tp&, _Tp&&>,
1424+
__is_nt_assignable_impl<_Tp, _Up>>
1425+
{ };
1426+
#endif
11281427

11291428
/// is_nothrow_assignable
11301429
template<typename _Tp, typename _Up>

0 commit comments

Comments
 (0)