30 #ifndef CEREAL_DETAILS_TRAITS_HPP_ 31 #define CEREAL_DETAILS_TRAITS_HPP_ 34 #if (__GNUC__ == 4 && __GNUC_MINOR__ <= 7) 35 #define CEREAL_OLDER_GCC 36 #endif // gcc 4.7 or earlier 39 #include <type_traits> 49 using yes = std::true_type;
50 using no = std::false_type;
61 #ifdef CEREAL_OLDER_GCC // when VS supports better SFINAE, we can use this as the default 62 template<
typename>
struct Void {
typedef void type; };
63 #endif // CEREAL_OLDER_GCC 70 template <
bool H,
bool ... T>
struct meta_bool_and : std::integral_constant<bool, H && meta_bool_and<T...>::value> {};
71 template <
bool B>
struct meta_bool_and<B> : std::integral_constant<bool, B> {};
73 template <
bool H,
bool ... T>
struct meta_bool_or : std::integral_constant<bool, H || meta_bool_or<T...>::value> {};
74 template <
bool B>
struct meta_bool_or<B> : std::integral_constant<bool, B> {};
78 template <
bool ... Conditions>
79 struct EnableIfHelper : std::enable_if<meta_bool_and<Conditions...>::value, sfinae> {};
81 template <
bool ... Conditions>
82 struct DisableIfHelper : std::enable_if<!meta_bool_or<Conditions...>::value, sfinae> {};
115 template <
bool ... Conditions>
116 using EnableIf =
typename detail::EnableIfHelper<Conditions...>::type;
147 template <
bool ... Conditions>
148 using DisableIf =
typename detail::DisableIfHelper<Conditions...>::type;
153 template <
class InputArchive>
157 "Could not find an associated output archive for input archive." );
160 template <
class OutputArchive>
164 "Could not find an associated input archive for output archive." );
169 #define CEREAL_SETUP_ARCHIVE_TRAITS(InputArchive, OutputArchive) \ 170 namespace cereal { namespace traits { namespace detail { \ 171 template <> struct get_output_from_input<InputArchive> \ 172 { using type = OutputArchive; }; \ 173 template <> struct get_input_from_output<OutputArchive> \ 174 { using type = InputArchive; }; } } } 178 #define CEREAL_MAKE_VERSIONED_TEST ,0 188 #ifdef CEREAL_OLDER_GCC 189 #define CEREAL_MAKE_HAS_MEMBER_TEST(name, test_name, versioned) \ 190 template <class T, class A, class SFINAE = void> \ 191 struct has_member_##test_name : no {}; \ 192 template <class T, class A> \ 193 struct has_member_##test_name<T, A, \ 194 typename detail::Void< decltype( cereal::access::member_##name( std::declval<A&>(), std::declval<T&>() versioned ) ) >::type> : yes {} 195 #else // NOT CEREAL_OLDER_GCC 196 #define CEREAL_MAKE_HAS_MEMBER_TEST(name, test_name, versioned) \ 199 template <class T, class A> \ 200 struct has_member_##name##_##versioned##_impl \ 202 template <class TT, class AA> \ 203 static auto test(int) -> decltype( cereal::access::member_##name( std::declval<AA&>(), std::declval<TT&>() versioned ), yes()); \ 204 template <class, class> \ 205 static no test(...); \ 206 static const bool value = std::is_same<decltype(test<T, A>(0)), yes>::value; \ 209 template <class T, class A> \ 210 struct has_member_##test_name : std::integral_constant<bool, detail::has_member_##name##_##versioned##_impl<T, A>::value> {} 211 #endif // NOT CEREAL_OLDER_GCC 217 #define CEREAL_MAKE_HAS_NON_MEMBER_TEST(test_name, func, versioned) \ 220 template <class T, class A> \ 221 struct has_non_member_##test_name##_impl \ 223 template <class TT, class AA> \ 224 static auto test(int) -> decltype( func( std::declval<AA&>(), std::declval<TT&>() versioned ), yes()); \ 225 template <class, class> \ 226 static no test( ... ); \ 227 static const bool value = std::is_same<decltype( test<T, A>( 0 ) ), yes>::value; \ 230 template <class T, class A> \ 231 struct has_non_member_##test_name : std::integral_constant<bool, detail::has_non_member_##test_name##_impl<T, A>::value> {} 266 #undef CEREAL_MAKE_HAS_NON_MEMBER_TEST 267 #undef CEREAL_MAKE_HAS_MEMBER_TEST 276 #ifdef CEREAL_OLDER_GCC 277 #define CEREAL_MAKE_HAS_MEMBER_SAVE_IMPL(test_name, versioned) \ 280 template <class T, class A> \ 281 struct has_member_##test_name##_impl \ 283 template <class TT, class AA, class SFINAE = void> struct test : no {}; \ 284 template <class TT, class AA> \ 285 struct test<TT, AA, \ 286 typename detail::Void< decltype( cereal::access::member_save( std::declval<AA&>(), \ 287 std::declval<TT const &>() versioned ) ) >::type> : yes {}; \ 288 static const bool value = test<T, A>(); \ 290 template <class TT, class AA, class SFINAE = void> struct test2 : no {}; \ 291 template <class TT, class AA> \ 292 struct test2<TT, AA, \ 293 typename detail::Void< decltype( cereal::access::member_save_non_const( \ 294 std::declval<AA&>(), \ 295 std::declval<typename std::remove_const<TT>::type&>() versioned ) ) >::type> : yes {}; \ 296 static const bool not_const_type = test2<T, A>(); \ 300 #define CEREAL_MAKE_HAS_MEMBER_SAVE_IMPL(test_name, versioned) \ 303 template <class T, class A> \ 304 struct has_member_##test_name##_impl \ 306 template <class TT, class AA> \ 307 static auto test(int) -> decltype( cereal::access::member_save( std::declval<AA&>(), \ 308 std::declval<TT const &>() versioned ), yes()); \ 309 template <class, class> static no test(...); \ 310 static const bool value = std::is_same<decltype(test<T, A>(0)), yes>::value; \ 312 template <class TT, class AA> \ 313 static auto test2(int) -> decltype( cereal::access::member_save_non_const( \ 314 std::declval<AA &>(), \ 315 std::declval<typename std::remove_const<TT>::type&>() versioned ), yes()); \ 316 template <class, class> static no test2(...); \ 317 static const bool not_const_type = std::is_same<decltype(test2<T, A>(0)), yes>::value; \ 326 template <class T, class A>
329 typedef typename detail::has_member_save_impl<T, A> check;
330 static_assert( check::value || !check::not_const_type,
331 "cereal detected a non-const save. \n " 332 "save member functions must always be const" );
339 template <
class T,
class A>
342 typedef typename detail::has_member_versioned_save_impl<T, A> check;
343 static_assert( check::value || !check::not_const_type,
344 "cereal detected a versioned non-const save. \n " 345 "save member functions must always be const" );
349 #undef CEREAL_MAKE_HAS_MEMBER_SAVE_IMPL 358 #define CEREAL_MAKE_HAS_NON_MEMBER_SAVE_TEST(test_name, versioned) \ 361 template <class T, class A> \ 362 struct has_non_member_##test_name##_impl \ 364 template <class TT, class AA> \ 365 static auto test(int) -> decltype( CEREAL_SAVE_FUNCTION_NAME( \ 366 std::declval<AA&>(), \ 367 std::declval<TT const &>() versioned ), yes()); \ 368 template <class, class> static no test(...); \ 369 static const bool value = std::is_same<decltype(test<T, A>(0)), yes>::value; \ 371 template <class TT, class AA> \ 372 static auto test2(int) -> decltype( CEREAL_SAVE_FUNCTION_NAME( \ 373 std::declval<AA &>(), \ 374 std::declval<typename std::remove_const<TT>::type&>() versioned ), yes()); \ 375 template <class, class> static no test2(...); \ 376 static const bool not_const_type = std::is_same<decltype(test2<T, A>(0)), yes>::value; \ 380 template <class T, class A> \ 381 struct has_non_member_##test_name : std::integral_constant<bool, detail::has_non_member_##test_name##_impl<T, A>::value> \ 383 using check = typename detail::has_non_member_##test_name##_impl<T, A>; \ 384 static_assert( check::value || !check::not_const_type, \ 385 "cereal detected a non-const type parameter in non-member " #test_name ". \n " \ 386 #test_name " non-member functions must always pass their types as const" ); \ 398 #undef CEREAL_MAKE_HAS_NON_MEMBER_SAVE_TEST 407 template <
class CharT,
class Traits,
class Alloc>
408 struct is_string<
std::basic_string<CharT, Traits, Alloc>> : std::true_type {};
414 detail::is_string<T>::value || std::is_arithmetic<T>::value> {};
423 #ifdef CEREAL_OLDER_GCC 424 #define CEREAL_MAKE_HAS_MEMBER_SAVE_MINIMAL_IMPL(test_name, versioned) \ 427 template <class T, class A> \ 428 struct has_member_##test_name##_impl \ 430 template <class TT, class AA, class SFINAE = void> struct test : no {}; \ 431 template <class TT, class AA> \ 432 struct test<TT, AA, typename detail::Void< decltype( \ 433 cereal::access::member_save_minimal( std::declval<AA const &>(), \ 434 std::declval<TT const &>() versioned ) ) >::type> : yes {}; \ 436 static const bool value = test<T, A>(); \ 438 template <class TT, class AA, class SFINAE = void> struct test2 : no {}; \ 439 template <class TT, class AA> \ 440 struct test2<TT, AA, typename detail::Void< decltype( \ 441 cereal::access::member_save_minimal_non_const( std::declval<AA const &>(), \ 442 std::declval<typename std::remove_const<TT>::type&>() versioned ) ) >::type> : yes {}; \ 443 static const bool not_const_type = test2<T, A>(); \ 445 static const bool valid = value || !not_const_type; \ 449 #define CEREAL_MAKE_HAS_MEMBER_SAVE_MINIMAL_IMPL(test_name, versioned) \ 452 template <class T, class A> \ 453 struct has_member_##test_name##_impl \ 455 template <class TT, class AA> \ 456 static auto test(int) -> decltype( cereal::access::member_save_minimal( \ 457 std::declval<AA const &>(), \ 458 std::declval<TT const &>() versioned ), yes()); \ 459 template <class, class> static no test(...); \ 460 static const bool value = std::is_same<decltype(test<T, A>(0)), yes>::value; \ 462 template <class TT, class AA> \ 463 static auto test2(int) -> decltype( cereal::access::member_save_minimal_non_const( \ 464 std::declval<AA const &>(), \ 465 std::declval<typename std::remove_const<TT>::type&>() versioned ), yes()); \ 466 template <class, class> static no test2(...); \ 467 static const bool not_const_type = std::is_same<decltype(test2<T, A>(0)), yes>::value; \ 469 static const bool valid = value || !not_const_type; \ 472 #endif // NOT CEREAL_OLDER_GCC 482 #define CEREAL_MAKE_HAS_MEMBER_SAVE_MINIMAL_HELPERS_IMPL(test_name, versioned) \ 485 template <class T, class A, bool Valid> \ 486 struct get_member_##test_name##_type { using type = void; }; \ 488 template <class T, class A> \ 489 struct get_member_##test_name##_type<T, A, true> \ 491 using type = decltype( cereal::access::member_save_minimal( std::declval<A const &>(), \ 492 std::declval<T const &>() versioned ) ); \ 502 #define CEREAL_MAKE_HAS_MEMBER_SAVE_MINIMAL_TEST(test_name) \ 503 template <class T, class A> \ 504 struct has_member_##test_name : std::integral_constant<bool, detail::has_member_##test_name##_impl<T, A>::value> \ 506 using check = typename detail::has_member_##test_name##_impl<T, A>; \ 507 static_assert( check::valid, \ 508 "cereal detected a non-const member " #test_name ". \n " \ 509 #test_name " member functions must always be const" ); \ 511 using type = typename detail::get_member_##test_name##_type<T, A, check::value>::type; \ 512 static_assert( (check::value && is_minimal_type<type>::value) || !check::value, \ 513 "cereal detected a member " #test_name " with an invalid return type. \n " \ 514 "return type must be arithmetic or string" ); \ 530 #undef CEREAL_MAKE_HAS_MEMBER_SAVE_MINIMAL_IMPL 531 #undef CEREAL_MAKE_HAS_MEMBER_SAVE_MINIMAL_HELPERS_IMPL 532 #undef CEREAL_MAKE_HAS_MEMBER_SAVE_MINIMAL_TEST 541 #define CEREAL_MAKE_HAS_NON_MEMBER_SAVE_MINIMAL_TEST(test_name, versioned) \ 544 template <class T, class A> \ 545 struct has_non_member_##test_name##_impl \ 547 template <class TT, class AA> \ 548 static auto test(int) -> decltype( CEREAL_SAVE_MINIMAL_FUNCTION_NAME( \ 549 std::declval<AA const &>(), \ 550 std::declval<TT const &>() versioned ), yes()); \ 551 template <class, class> static no test(...); \ 552 static const bool value = std::is_same<decltype(test<T, A>(0)), yes>::value; \ 554 template <class TT, class AA> \ 555 static auto test2(int) -> decltype( CEREAL_SAVE_MINIMAL_FUNCTION_NAME( \ 556 std::declval<AA const &>(), \ 557 std::declval<typename std::remove_const<TT>::type&>() versioned ), yes()); \ 558 template <class, class> static no test2(...); \ 559 static const bool not_const_type = std::is_same<decltype(test2<T, A>(0)), yes>::value; \ 561 static const bool valid = value || !not_const_type; \ 564 template <class T, class A, bool Valid> \ 565 struct get_non_member_##test_name##_type { using type = void; }; \ 567 template <class T, class A> \ 568 struct get_non_member_##test_name##_type <T, A, true> \ 570 using type = decltype( CEREAL_SAVE_MINIMAL_FUNCTION_NAME( std::declval<A const &>(), \ 571 std::declval<T const &>() versioned ) ); \ 575 template <class T, class A> \ 576 struct has_non_member_##test_name : std::integral_constant<bool, detail::has_non_member_##test_name##_impl<T, A>::value> \ 578 using check = typename detail::has_non_member_##test_name##_impl<T, A>; \ 579 static_assert( check::valid, \ 580 "cereal detected a non-const type parameter in non-member " #test_name ". \n " \ 581 #test_name " non-member functions must always pass their types as const" ); \ 583 using type = typename detail::get_non_member_##test_name##_type<T, A, check::value>::type; \ 584 static_assert( (check::value && is_minimal_type<type>::value) || !check::value, \ 585 "cereal detected a non-member " #test_name " with an invalid return type. \n " \ 586 "return type must be arithmetic or string" ); \ 598 #undef CEREAL_MAKE_HAS_NON_MEMBER_SAVE_MINIMAL_TEST 617 template <
class Source>
622 template <class Dest, class = typename std::enable_if<std::is_same<Source, Dest>::value>
::type>
623 operator Dest () =
delete;
626 template <class Dest, class = typename std::enable_if<std::is_same<Source, Dest>::value>
::type>
627 operator Dest
const & ();
635 template <
class Source>
640 template <class Dest, class = typename std::enable_if<std::is_same<Source, Dest>::value>
::type>
641 operator Dest () =
delete;
644 template <class Dest, class = typename std::enable_if<std::is_same<Source, Dest>::value>
::type>
645 operator Dest
const & () =
delete;
649 template <class Dest, class = typename std::enable_if<std::is_same<Source, Dest>::value>
::type>
656 template <
class Dest>
659 template <
class Dest>
660 operator Dest
const & ()
const;
675 #ifdef CEREAL_OLDER_GCC 676 #define CEREAL_MAKE_HAS_MEMBER_LOAD_MINIMAL_IMPL(test_name, versioned) \ 679 template <class T, class A, class SFINAE = void> struct has_member_##test_name##_impl : no {}; \ 680 template <class T, class A> \ 681 struct has_member_##test_name##_impl<T, A, typename detail::Void< decltype( \ 682 cereal::access::member_load_minimal( std::declval<A const &>(), \ 683 std::declval<T &>(), AnyConvert() versioned ) ) >::type> : yes {}; \ 685 template <class T, class A, class U, class SFINAE = void> struct has_member_##test_name##_type_impl : no {}; \ 686 template <class T, class A, class U> \ 687 struct has_member_##test_name##_type_impl<T, A, U, typename detail::Void< decltype( \ 688 cereal::access::member_load_minimal( std::declval<A const &>(), \ 689 std::declval<T &>(), NoConvertConstRef<U>() versioned ) ) >::type> : yes {}; \ 692 #define CEREAL_MAKE_HAS_MEMBER_LOAD_MINIMAL_IMPL(test_name, versioned) \ 695 template <class T, class A> \ 696 struct has_member_##test_name##_impl \ 698 template <class TT, class AA> \ 699 static auto test(int) -> decltype( cereal::access::member_load_minimal( \ 700 std::declval<AA const &>(), \ 701 std::declval<TT &>(), AnyConvert() versioned ), yes()); \ 702 template <class, class> static no test(...); \ 703 static const bool value = std::is_same<decltype(test<T, A>(0)), yes>::value; \ 705 template <class T, class A, class U> \ 706 struct has_member_##test_name##_type_impl \ 708 template <class TT, class AA, class UU> \ 709 static auto test(int) -> decltype( cereal::access::member_load_minimal( \ 710 std::declval<AA const &>(), \ 711 std::declval<TT &>(), NoConvertConstRef<UU>() versioned ), yes()); \ 712 template <class, class, class> static no test(...); \ 713 static const bool value = std::is_same<decltype(test<T, A, U>(0)), yes>::value; \ 717 #endif // NOT CEREAL_OLDER_GCC 731 #define CEREAL_MAKE_HAS_MEMBER_LOAD_MINIMAL_HELPERS_IMPL(load_test_name, save_test_name, save_test_prefix, versioned) \ 734 template <class T, class A, bool Valid> \ 735 struct has_member_##load_test_name##_wrapper : std::false_type {}; \ 737 template <class T, class A> \ 738 struct has_member_##load_test_name##_wrapper<T, A, true> \ 740 using AOut = typename detail::get_output_from_input<A>::type; \ 742 static_assert( has_member_##save_test_prefix##_minimal<T, AOut>::value, \ 743 "cereal detected member " #load_test_name " but no valid member " #save_test_name ". \n " \ 744 "cannot evaluate correctness of " #load_test_name " without valid " #save_test_name "." ); \ 746 using SaveType = typename detail::get_member_##save_test_prefix##_minimal_type<T, AOut, true>::type; \ 747 const static bool value = has_member_##load_test_name##_impl<T, A>::value; \ 748 const static bool valid = has_member_##load_test_name##_type_impl<T, A, SaveType>::value; \ 750 static_assert( valid || !value, "cereal detected different or invalid types in corresponding member " \ 751 #load_test_name " and " #save_test_name " functions. \n " \ 752 "the paramater to " #load_test_name " must be a constant reference to the type that " \ 753 #save_test_name " returns." ); \ 764 #define CEREAL_MAKE_HAS_MEMBER_LOAD_MINIMAL_TEST(load_test_name, load_test_prefix) \ 765 template <class T, class A> \ 766 struct has_member_##load_test_prefix##_minimal : std::integral_constant<bool, \ 767 detail::has_member_##load_test_name##_wrapper<T, A, detail::has_member_##load_test_name##_impl<T, A>::value>::value> {}; 782 #undef CEREAL_MAKE_HAS_MEMBER_LOAD_MINIMAL_IMPL 783 #undef CEREAL_MAKE_HAS_MEMBER_LOAD_MINIMAL_HELPERS_IMPL 784 #undef CEREAL_MAKE_HAS_MEMBER_LOAD_MINIMAL_TEST 790 #ifdef CEREAL_OLDER_GCC 793 #endif // CEREAL_OLDER_GCC 806 #define CEREAL_MAKE_HAS_NON_MEMBER_LOAD_MINIMAL_TEST(test_name, save_name, versioned) \ 809 template <class T, class A, class U = void> \ 810 struct has_non_member_##test_name##_impl \ 812 template <class TT, class AA> \ 813 static auto test(int) -> decltype( CEREAL_LOAD_MINIMAL_FUNCTION_NAME( \ 814 std::declval<AA const &>(), std::declval<TT&>(), AnyConvert() versioned ), yes() ); \ 815 template <class, class> static no test( ... ); \ 816 static const bool exists = std::is_same<decltype( test<T, A>( 0 ) ), yes>::value; \ 818 template <class TT, class AA, class UU> \ 819 static auto test2(int) -> decltype( CEREAL_LOAD_MINIMAL_FUNCTION_NAME( \ 820 std::declval<AA const &>(), std::declval<TT&>(), NoConvertConstRef<UU>() versioned ), yes() ); \ 821 template <class, class, class> static no test2( ... ); \ 822 static const bool valid = std::is_same<decltype( test2<T, A, U>( 0 ) ), yes>::value; \ 824 template <class TT, class AA> \ 825 static auto test3(int) -> decltype( CEREAL_LOAD_MINIMAL_FUNCTION_NAME( \ 826 std::declval<AA const &>(), NoConvertRef<TT>(), AnyConvert() versioned ), yes() ); \ 827 template <class, class> static no test3( ... ); \ 828 static const bool const_valid = std::is_same<decltype( test3<T, A>( 0 ) ), yes>::value; \ 831 template <class T, class A, bool Valid> \ 832 struct has_non_member_##test_name##_wrapper : std::false_type {}; \ 834 template <class T, class A> \ 835 struct has_non_member_##test_name##_wrapper<T, A, true> \ 837 using AOut = typename detail::get_output_from_input<A>::type; \ 839 static_assert( detail::has_non_member_##save_name##_impl<T, AOut>::valid, \ 840 "cereal detected non-member " #test_name " but no valid non-member " #save_name ". \n " \ 841 "cannot evaluate correctness of " #test_name " without valid " #save_name "." ); \ 843 using SaveType = typename detail::get_non_member_##save_name##_type<T, AOut, true>::type; \ 844 using check = has_non_member_##test_name##_impl<T, A, SaveType>; \ 845 static const bool value = check::exists; \ 847 static_assert( check::valid || !check::exists, "cereal detected different types in corresponding non-member " \ 848 #test_name " and " #save_name " functions. \n " \ 849 "the paramater to " #test_name " must be a constant reference to the type that " #save_name " returns." ); \ 850 static_assert( check::const_valid || !check::exists, \ 851 "cereal detected an invalid serialization type parameter in non-member " #test_name ". " \ 852 #test_name " non-member functions must accept their serialization type by non-const reference" ); \ 856 template <class T, class A> \ 857 struct has_non_member_##test_name : std::integral_constant<bool, \ 858 detail::has_non_member_##test_name##_wrapper<T, A, detail::has_non_member_##test_name##_impl<T, A>::exists>::value> {}; 869 #undef CEREAL_MAKE_HAS_NON_MEMBER_LOAD_MINIMAL_TEST 873 #undef CEREAL_MAKE_VERSIONED_TEST 876 template <
class T,
class InputArchive,
class OutputArchive>
878 (has_member_load<T, InputArchive>::value && has_member_save<T, OutputArchive>::value) ||
879 (has_member_versioned_load<T, InputArchive>::value && has_member_versioned_save<T, OutputArchive>::value)> {};
882 template <
class T,
class InputArchive,
class OutputArchive>
884 (has_non_member_load<T, InputArchive>::value && has_non_member_save<T, OutputArchive>::value) ||
885 (has_non_member_versioned_load<T, InputArchive>::value && has_non_member_versioned_save<T, OutputArchive>::value)> {};
888 template <
class T,
class OutputArchive>
890 (has_member_versioned_save<T, OutputArchive>::value && has_member_save<T, OutputArchive>::value) ||
891 (has_non_member_versioned_save<T, OutputArchive>::value && has_non_member_save<T, OutputArchive>::value) ||
892 (has_member_versioned_serialize<T, OutputArchive>::value && has_member_serialize<T, OutputArchive>::value) ||
893 (has_non_member_versioned_serialize<T, OutputArchive>::value && has_non_member_serialize<T, OutputArchive>::value) ||
894 (has_member_versioned_save_minimal<T, OutputArchive>::value && has_member_save_minimal<T, OutputArchive>::value) ||
895 (has_non_member_versioned_save_minimal<T, OutputArchive>::value && has_non_member_save_minimal<T, OutputArchive>::value)> {};
898 template <
class T,
class InputArchive>
900 (has_member_versioned_load<T, InputArchive>::value && has_member_load<T, InputArchive>::value) ||
901 (has_non_member_versioned_load<T, InputArchive>::value && has_non_member_load<T, InputArchive>::value) ||
902 (has_member_versioned_serialize<T, InputArchive>::value && has_member_serialize<T, InputArchive>::value) ||
903 (has_non_member_versioned_serialize<T, InputArchive>::value && has_non_member_serialize<T, InputArchive>::value) ||
904 (has_member_versioned_load_minimal<T, InputArchive>::value && has_member_load_minimal<T, InputArchive>::value) ||
905 (has_non_member_versioned_load_minimal<T, InputArchive>::value && has_non_member_load_minimal<T, InputArchive>::value)> {};
911 #define CEREAL_MAKE_IS_SPECIALIZED_IMPL(name) \ 912 template <class T, class A> \ 913 struct is_specialized_##name : std::integral_constant<bool, \ 914 !std::is_base_of<std::false_type, specialize<A, T, specialization::name>>::value> {} 923 #undef CEREAL_MAKE_IS_SPECIALIZED_IMPL 926 template <
class T,
class A>
928 is_specialized_member_serialize<T, A>::value +
929 is_specialized_member_load_save<T, A>::value +
930 is_specialized_member_load_save_minimal<T, A>::value +
931 is_specialized_non_member_serialize<T, A>::value +
932 is_specialized_non_member_load_save<T, A>::value +
933 is_specialized_non_member_load_save_minimal<T, A>::value> {};
937 template <
class T,
class A>
939 detail::is_specialized_member_serialize<T, A>::value ||
940 detail::is_specialized_member_load_save<T, A>::value ||
941 detail::is_specialized_member_load_save_minimal<T, A>::value ||
942 detail::is_specialized_non_member_serialize<T, A>::value ||
943 detail::is_specialized_non_member_load_save<T, A>::value ||
944 detail::is_specialized_non_member_load_save_minimal<T, A>::value>
952 #define CEREAL_MAKE_IS_SPECIALIZED_ASSERT(name, versioned_name, print_name, spec_name) \ 953 static_assert( (is_specialized<T, A>::value && detail::is_specialized_##spec_name<T, A>::value && \ 954 (has_##name<T, A>::value || has_##versioned_name<T, A>::value)) \ 955 || !(is_specialized<T, A>::value && detail::is_specialized_##spec_name<T, A>::value), \ 956 "cereal detected " #print_name " specialization but no " #print_name " serialize function" ) 961 #define CEREAL_MAKE_IS_SPECIALIZED(name, versioned_name, spec_name) \ 962 template <class T, class A> \ 963 struct is_specialized_##name : std::integral_constant<bool, \ 964 is_specialized<T, A>::value && detail::is_specialized_##spec_name<T, A>::value> \ 965 { CEREAL_MAKE_IS_SPECIALIZED_ASSERT(name, versioned_name, name, spec_name); }; \ 966 template <class T, class A> \ 967 struct is_specialized_##versioned_name : std::integral_constant<bool, \ 968 is_specialized<T, A>::value && detail::is_specialized_##spec_name<T, A>::value> \ 969 { CEREAL_MAKE_IS_SPECIALIZED_ASSERT(name, versioned_name, versioned_name, spec_name); } 984 #undef CEREAL_MAKE_IS_SPECIALIZED_ASSERT 985 #undef CEREAL_MAKE_IS_SPECIALIZED 989 template <
class T,
class OutputArchive>
991 is_specialized_member_save_minimal<T, OutputArchive>::value ||
992 ((has_member_save_minimal<T, OutputArchive>::value ||
993 has_non_member_save_minimal<T, OutputArchive>::value ||
994 has_member_versioned_save_minimal<T, OutputArchive>::value ||
995 has_non_member_versioned_save_minimal<T, OutputArchive>::value) &&
996 !(is_specialized_member_serialize<T, OutputArchive>::value ||
997 is_specialized_member_save<T, OutputArchive>::value))> {};
1001 template <
class T,
class InputArchive>
1003 is_specialized_member_load_minimal<T, InputArchive>::value ||
1004 ((has_member_load_minimal<T, InputArchive>::value ||
1005 has_non_member_load_minimal<T, InputArchive>::value ||
1006 has_member_versioned_load_minimal<T, InputArchive>::value ||
1007 has_non_member_versioned_load_minimal<T, InputArchive>::value) &&
1008 !(is_specialized_member_serialize<T, InputArchive>::value ||
1009 is_specialized_member_load<T, InputArchive>::value))> {};
1016 template <
class T,
class OutputArchive>
1018 count_specializations<T, OutputArchive>::value ? count_specializations<T, OutputArchive>::value :
1019 has_member_save<T, OutputArchive>::value +
1020 has_non_member_save<T, OutputArchive>::value +
1021 has_member_serialize<T, OutputArchive>::value +
1022 has_non_member_serialize<T, OutputArchive>::value +
1023 has_member_save_minimal<T, OutputArchive>::value +
1024 has_non_member_save_minimal<T, OutputArchive>::value +
1026 has_member_versioned_save<T, OutputArchive>::value +
1027 has_non_member_versioned_save<T, OutputArchive>::value +
1028 has_member_versioned_serialize<T, OutputArchive>::value +
1029 has_non_member_versioned_serialize<T, OutputArchive>::value +
1030 has_member_versioned_save_minimal<T, OutputArchive>::value +
1031 has_non_member_versioned_save_minimal<T, OutputArchive>::value> {};
1034 template <
class T,
class OutputArchive>
1036 detail::count_output_serializers<T, OutputArchive>::value == 1> {};
1043 template <
class T,
class InputArchive>
1045 count_specializations<T, InputArchive>::value ? count_specializations<T, InputArchive>::value :
1046 has_member_load<T, InputArchive>::value +
1047 has_non_member_load<T, InputArchive>::value +
1048 has_member_serialize<T, InputArchive>::value +
1049 has_non_member_serialize<T, InputArchive>::value +
1050 has_member_load_minimal<T, InputArchive>::value +
1051 has_non_member_load_minimal<T, InputArchive>::value +
1053 has_member_versioned_load<T, InputArchive>::value +
1054 has_non_member_versioned_load<T, InputArchive>::value +
1055 has_member_versioned_serialize<T, InputArchive>::value +
1056 has_non_member_versioned_serialize<T, InputArchive>::value +
1057 has_member_versioned_load_minimal<T, InputArchive>::value +
1058 has_non_member_versioned_load_minimal<T, InputArchive>::value> {};
1061 template <
class T,
class InputArchive>
1063 detail::count_input_serializers<T, InputArchive>::value == 1> {};
1075 hash(std::hash<std::type_index>()(
typeid(T)) ^ (std::hash<void const *>()(t) << 1))
1079 {
return (type == other.type) && (ptr == other.ptr); }
1081 std::type_index type;
1096 template <
template<
typename>
class Cast,
class Base>
1103 template <
class Cast,
template<
class,
class>
class Test,
class Archive,
1104 bool IsBaseCast = std::is_base_of<BaseCastBase, Cast>::value>
1109 template <
class Cast,
template<
class,
class>
class Test,
class Archive>
1118 template <
class Cast,
template<
class,
class>
class Test,
class Archive>
1129 static auto check( U
const & t ) -> decltype( ::cereal::access::shared_from_this(t), std::true_type() );
1131 static auto check( ... ) -> decltype( std::false_type() );
1134 static auto get( U
const & t ) -> decltype( t.shared_from_this() );
1148 using PtrType = decltype(detail::shared_from_this_wrapper::get(std::declval<T>()));
1151 using type =
typename std::decay<typename PtrType::element_type>::type;
1162 template <class T, bool IsCerealMinimalTrait = std::is_base_of<detail::NoConvertBase, T>::value>
1172 using type =
typename T::type;
1177 template<
typename T,
typename A>
1179 std::is_same<decltype( access::load_and_construct<T>( std::declval<A&>(), std::declval< ::cereal::construct<T>&>() ) ), void>::value>
1184 template<
typename T,
typename A>
1186 std::is_same<decltype( LoadAndConstruct<T>::load_and_construct( std::declval<A&>(), std::declval< ::cereal::construct<T>&>() ) ), void>::value>
1191 template<
typename T,
typename A>
1193 has_member_load_and_construct<T, A>::value || has_non_member_load_and_construct<T, A>::value>
1201 #ifdef CEREAL_OLDER_GCC 1202 template <
class TT,
class SFINAE =
void>
1203 struct test : no {};
1205 struct test<TT, typename detail::Void< decltype( cereal::access::construct<TT>() ) >::type> : yes {};
1206 static const bool value = test<T>();
1207 #else // NOT CEREAL_OLDER_GCC ========================================= 1209 static auto test(
int) -> decltype( cereal::access::construct<TT>(), yes());
1211 static no test(...);
1212 static const bool value = std::is_same<decltype(test<T>(0)), yes>::value;
1213 #endif // NOT CEREAL_OLDER_GCC 1221 using decay_archive =
typename std::decay<typename strip_minimal<A>::type>::type;
1234 template <
class ArchiveT,
class CerealArchiveT>
1236 std::is_same<detail::decay_archive<ArchiveT>, CerealArchiveT>::value>
1260 #define CEREAL_ARCHIVE_RESTRICT(INTYPE, OUTTYPE) \ 1261 typename std::enable_if<cereal::traits::is_same_archive<Archive, INTYPE>::value || cereal::traits::is_same_archive<Archive, OUTTYPE>::value, void>::type 1271 std::is_base_of<TextArchive, detail::decay_archive<A>>::value>
1282 "Cereal detected both member and non member load_and_construct functions!" );
1283 static T * load_andor_construct( A & ,
construct<T> & )
1287 template <
class T,
class A>
1291 "Trying to serialize a an object with no default constructor. \n\n " 1292 "Types must either be default constructible or define either a member or non member Construct function. \n " 1293 "Construct functions generally have the signature: \n\n " 1294 "template <class Archive> \n " 1295 "static void load_and_construct(Archive & ar, cereal::construct<T> & construct) \n " 1299 " construct( a ); \n " 1301 static T * load_andor_construct()
1302 { return ::cereal::access::construct<T>(); }
1305 template <
class T,
class A>
1310 access::load_and_construct<T>( ar, construct );
1314 template <
class T,
class A>
1325 #endif // CEREAL_DETAILS_TRAITS_HPP_ #define CEREAL_MAKE_HAS_MEMBER_SAVE_MINIMAL_TEST(test_name)
Creates a test for whether a member save_minimal function exists.
Definition: traits.hpp:502
Has either a member or non member allocate.
Definition: traits.hpp:1192
Definition: traits.hpp:79
Definition: traits.hpp:413
Definition: traits.hpp:82
Check if any specialization exists for a type.
Definition: traits.hpp:938
Determines whether the class T can be default constructed by cereal::access.
Definition: traits.hpp:1199
Extracts the true type from something possibly wrapped in a cereal NoConvert.
Definition: traits.hpp:1163
The number of output serialization functions available.
Definition: traits.hpp:1017
Common base type for base class casting.
Definition: traits.hpp:1091
Source type
Used to get underlying type easily.
Definition: traits.hpp:638
Used to delay a static_assert until template instantiation.
Definition: traits.hpp:57
typename detail::EnableIfHelper< Conditions... >::type EnableIf
Provides a way to enable a function if conditions are met.
Definition: traits.hpp:116
Checks to see if the base class used in a cast has a minimal serialization.
Definition: traits.hpp:1119
Used to construct types with no default constructor.
Definition: access.hpp:151
static std::false_type load_and_construct(...)
Called by cereal if no default constructor exists to load and construct data simultaneously.
Definition: access.hpp:95
Checks if the provided archive type is equal to some cereal archive type.
Definition: traits.hpp:1235
Type traits only struct used to mark an archive as human readable (text based)
Definition: traits.hpp:1266
#define CEREAL_MAKE_HAS_MEMBER_LOAD_MINIMAL_TEST(load_test_name, load_test_prefix)
Creates a test for whether a member load_minimal function exists.
Definition: traits.hpp:764
Definition: traits.hpp:340
#define CEREAL_SERIALIZE_FUNCTION_NAME
The serialization/deserialization function name to search for.
Definition: macros.hpp:51
typename std::decay< typename PtrType::element_type >::type type
The type of the base of T that inherited from std::enable_shared_from_this.
Definition: traits.hpp:1151
A struct that prevents implicit conversion.
Definition: traits.hpp:636
Source type
Used to get underlying type easily.
Definition: traits.hpp:620
#define CEREAL_SAVE_MINIMAL_FUNCTION_NAME
The serialization (save_minimal) function name to search for.
Definition: macros.hpp:79
A struct that prevents implicit conversion.
Definition: traits.hpp:618
#define CEREAL_MAKE_HAS_NON_MEMBER_SAVE_TEST(test_name, versioned)
Creates a test for whether a non-member save function exists.
Definition: traits.hpp:358
Definition: traits.hpp:1085
Checks if an archive is a text archive (human readable)
Definition: traits.hpp:1270
#define CEREAL_MAKE_IS_SPECIALIZED(name, versioned_name, spec_name)
Generates a test for specialization for versioned and unversioned functions.
Definition: traits.hpp:961
Definition: traits.hpp:889
#define CEREAL_MAKE_HAS_MEMBER_SAVE_MINIMAL_IMPL(test_name, versioned)
Creates implementation details for whether a member save_minimal function exists. ...
Definition: traits.hpp:449
Definition: traits.hpp:877
Member load and construct check.
Definition: traits.hpp:1178
#define CEREAL_MAKE_HAS_NON_MEMBER_TEST(test_name, func, versioned)
Creates a test for whether a non const non-member function exists.
Definition: traits.hpp:217
Determine if T or any base class of T has inherited from std::enable_shared_from_this.
Definition: traits.hpp:1140
Get the type of the base class of T which inherited from std::enable_shared_from_this.
Definition: traits.hpp:1145
Definition: traits.hpp:990
Definition: access.hpp:39
#define CEREAL_MAKE_HAS_NON_MEMBER_LOAD_MINIMAL_TEST(test_name, save_name, versioned)
Creates a test for whether a non-member load_minimal function exists.
Definition: traits.hpp:806
typename std::decay< typename strip_minimal< A >::type >::type decay_archive
Removes all qualifiers and minimal wrappers from an archive.
Definition: traits.hpp:1221
Access control, default construction, and serialization disambiguation.
sfinae
Return type for SFINAE Enablers.
Definition: traits.hpp:66
Definition: traits.hpp:1035
#define CEREAL_MAKE_IS_SPECIALIZED_IMPL(name)
Create a test for a cereal::specialization entry.
Definition: traits.hpp:911
Definition: traits.hpp:883
Preprocessor macros that can customise the cereal library.
#define CEREAL_LOAD_FUNCTION_NAME
The deserialization (load) function name to search for.
Definition: macros.hpp:58
#define CEREAL_LOAD_MINIMAL_FUNCTION_NAME
The deserialization (load_minimal) function name to search for.
Definition: macros.hpp:72
Used to help strip away conversion wrappers.
Definition: traits.hpp:610
Number of specializations detected.
Definition: traits.hpp:927
A type that can implicitly convert to anything else.
Definition: traits.hpp:654
#define CEREAL_MAKE_HAS_MEMBER_LOAD_MINIMAL_IMPL(test_name, versioned)
Creates a test for whether a member load_minimal function exists.
Definition: traits.hpp:692
#define CEREAL_MAKE_VERSIONED_TEST
Used to convert a MAKE_HAS_XXX macro into a versioned variant.
Definition: traits.hpp:178
Definition: traits.hpp:405
#define CEREAL_MAKE_HAS_MEMBER_SAVE_IMPL(test_name, versioned)
Creates a test for whether a member save function exists.
Definition: traits.hpp:300
#define CEREAL_MAKE_HAS_MEMBER_LOAD_MINIMAL_HELPERS_IMPL(load_test_name, save_test_name, save_test_prefix, versioned)
Creates helpers for minimal load functions.
Definition: traits.hpp:731
Definition: traits.hpp:1126
Base class cast, behave as the test.
Definition: traits.hpp:1105
#define CEREAL_MAKE_HAS_MEMBER_TEST(name, test_name, versioned)
Creates a test for whether a non const member function exists.
Definition: traits.hpp:196
#define CEREAL_MAKE_HAS_NON_MEMBER_SAVE_MINIMAL_TEST(test_name, versioned)
Creates a test for whether a non-member save_minimal function exists.
Definition: traits.hpp:541
Definition: traits.hpp:1279
Definition: traits.hpp:1094
Non member load and construct check.
Definition: traits.hpp:1185
Definition: traits.hpp:1069
typename detail::DisableIfHelper< Conditions... >::type DisableIf
Provides a way to disable a function if conditions are met.
Definition: traits.hpp:148
#define CEREAL_MAKE_HAS_MEMBER_SAVE_MINIMAL_HELPERS_IMPL(test_name, versioned)
Creates helpers for minimal save functions.
Definition: traits.hpp:482
Definition: traits.hpp:327