30#ifndef CEREAL_DETAILS_TRAITS_HPP_ 
   31#define CEREAL_DETAILS_TRAITS_HPP_ 
   34#if (__GNUC__ == 4 && __GNUC_MINOR__ <= 7) 
   35#define CEREAL_OLDER_GCC 
   49    using yes = std::true_type;
 
   50    using no  = std::false_type;
 
   61      #ifdef CEREAL_OLDER_GCC  
   62      template<
typename> 
struct Void { 
typedef void type; };
 
   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 {} 
  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> {} 
  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>
 
  327    struct 
has_member_save : std::integral_constant<
bool, detail::has_member_save_impl<T, A>::value>
 
  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;                                    \ 
  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; \ 
  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 
  818    #define CEREAL_MAKE_HAS_NON_MEMBER_LOAD_MINIMAL_TEST(test_name, save_name, versioned)                                    \ 
  821      template <class T, class A, class U = void>                                                                            \ 
  822      struct has_non_member_##test_name##_impl                                                                               \ 
  824        template <class TT, class AA>                                                                                        \ 
  825        static auto test(int) -> decltype( CEREAL_LOAD_MINIMAL_FUNCTION_NAME(                                                \ 
  826              std::declval<AA const &>(), std::declval<TT&>(), AnyConvert() versioned ), yes() );                            \ 
  827        template <class, class> static no test( ... );                                                                       \ 
  828        static const bool exists = std::is_same<decltype( test<T, A>( 0 ) ), yes>::value;                                    \ 
  830        template <class TT, class AA, class UU>                                                                              \ 
  831        static auto test2(int) -> decltype( CEREAL_LOAD_MINIMAL_FUNCTION_NAME(                                               \ 
  832              std::declval<AA const &>(), std::declval<TT&>(), NoConvertConstRef<UU>() versioned ), yes() );                 \ 
  833        template <class, class, class> static no test2( ... );                                                               \ 
  834        static const bool valid = std::is_same<decltype( test2<T, A, U>( 0 ) ), yes>::value;                                 \ 
  836        template <class TT, class AA>                                                                                        \ 
  837        static auto test3(int) -> decltype( CEREAL_LOAD_MINIMAL_FUNCTION_NAME(                                               \ 
  838              std::declval<AA const &>(), NoConvertRef<TT>(), AnyConvert() versioned ), yes() );                             \ 
  839        template <class, class> static no test3( ... );                                                                      \ 
  840        static const bool const_valid = std::is_same<decltype( test3<T, A>( 0 ) ), yes>::value;                              \ 
  843      template <class T, class A, bool Valid>                                                                                \ 
  844      struct has_non_member_##test_name##_wrapper : std::false_type {};                                                      \ 
  846      template <class T, class A>                                                                                            \ 
  847      struct has_non_member_##test_name##_wrapper<T, A, true>                                                                \ 
  849        using AOut = typename detail::get_output_from_input<A>::type;                                                        \ 
  851        static_assert( detail::has_non_member_##save_name##_impl<T, AOut>::valid,                                            \ 
  852          "cereal detected non-member " #test_name " but no valid non-member " #save_name ". \n "                            \
 
  853          "cannot evaluate correctness of " #test_name " without valid " #save_name "." );                                   \
 
  855        using SaveType = typename detail::get_non_member_##save_name##_type<T, AOut, true>::type;                            \
 
  856        using check = has_non_member_##test_name##_impl<T, A, SaveType>;                                                     \
 
  857        static const bool value = check::exists;                                                                             \
 
  859        static_assert( check::valid || !check::exists, "cereal detected different types in corresponding non-member "        \
 
  860            #test_name " and " #save_name " functions. \n "                                                                  \
 
  861            "the paramater to " #test_name " must be a constant reference to the type that " #save_name " returns." );       \
 
  865    template <class T, class A>                                                                                              \ 
  866    struct has_non_member_##test_name : std::integral_constant<bool,                                                         \ 
  867      detail::has_non_member_##test_name##_wrapper<T, A, detail::has_non_member_##test_name##_impl<T, A>::exists>::value> {}; 
  878    #undef CEREAL_MAKE_HAS_NON_MEMBER_LOAD_MINIMAL_TEST 
  885      template<
typename T, 
typename A>
 
  887        std::is_same<decltype( access::load_and_construct<T>( std::declval<A&>(), std::declval< ::cereal::construct<T>&>() ) ), void>::value>
 
  890      template<
typename T, 
typename A>
 
  892        std::is_same<decltype( access::load_and_construct<T>( std::declval<A&>(), std::declval< ::cereal::construct<T>&>(), 0 ) ), void>::value>
 
  897    template<
typename T, 
typename A>
 
  902    template<
typename T, 
typename A>
 
  910    #define CEREAL_MAKE_HAS_NON_MEMBER_LOAD_AND_CONSTRUCT_TEST(test_name, versioned)                                            \ 
  913      template <class T, class A>                                                                                               \ 
  914      struct has_non_member_##test_name##_impl                                                                                  \ 
  916        template <class TT, class AA>                                                                                           \ 
  917        static auto test(int) -> decltype( LoadAndConstruct<TT>::load_and_construct(                                            \ 
  918                                           std::declval<AA&>(), std::declval< ::cereal::construct<TT>&>() versioned ), yes());  \ 
  919        template <class, class>                                                                                                 \ 
  920        static no test( ... );                                                                                                  \ 
  921        static const bool value = std::is_same<decltype( test<T, A>( 0 ) ), yes>::value;                                        \ 
  924    template <class T, class A>                                                                                                 \ 
  925    struct has_non_member_##test_name :                                                                                         \ 
  926      std::integral_constant<bool, detail::has_non_member_##test_name##_impl<typename std::remove_const<T>::type, A>::value> {}; 
  938    template<typename T, typename A>
 
  945    #undef CEREAL_MAKE_HAS_NON_MEMBER_LOAD_AND_CONSTRUCT_TEST 
  949    #undef CEREAL_MAKE_VERSIONED_TEST 
  952    template <
class T, 
class InputArchive, 
class OutputArchive>
 
  954      (has_member_load<T, InputArchive>::value && has_member_save<T, OutputArchive>::value) ||
 
  955      (has_member_versioned_load<T, InputArchive>::value && has_member_versioned_save<T, OutputArchive>::value)> {};
 
  958    template <
class T, 
class InputArchive, 
class OutputArchive>
 
  960      (has_non_member_load<T, InputArchive>::value && has_non_member_save<T, OutputArchive>::value) ||
 
  961      (has_non_member_versioned_load<T, InputArchive>::value && has_non_member_versioned_save<T, OutputArchive>::value)> {};
 
  964    template <
class T, 
class OutputArchive>
 
  966      (has_member_versioned_save<T, OutputArchive>::value && has_member_save<T, OutputArchive>::value) ||
 
  967      (has_non_member_versioned_save<T, OutputArchive>::value && has_non_member_save<T, OutputArchive>::value) ||
 
  968      (has_member_versioned_serialize<T, OutputArchive>::value && has_member_serialize<T, OutputArchive>::value) ||
 
  969      (has_non_member_versioned_serialize<T, OutputArchive>::value && has_non_member_serialize<T, OutputArchive>::value) ||
 
  970      (has_member_versioned_save_minimal<T, OutputArchive>::value && has_member_save_minimal<T, OutputArchive>::value) ||
 
  971      (has_non_member_versioned_save_minimal<T, OutputArchive>::value &&  has_non_member_save_minimal<T, OutputArchive>::value)> {};
 
  974    template <
class T, 
class InputArchive>
 
  976      (has_member_versioned_load<T, InputArchive>::value && has_member_load<T, InputArchive>::value) ||
 
  977      (has_non_member_versioned_load<T, InputArchive>::value && has_non_member_load<T, InputArchive>::value) ||
 
  978      (has_member_versioned_serialize<T, InputArchive>::value && has_member_serialize<T, InputArchive>::value) ||
 
  979      (has_non_member_versioned_serialize<T, InputArchive>::value && has_non_member_serialize<T, InputArchive>::value) ||
 
  980      (has_member_versioned_load_minimal<T, InputArchive>::value && has_member_load_minimal<T, InputArchive>::value) ||
 
  981      (has_non_member_versioned_load_minimal<T, InputArchive>::value &&  has_non_member_load_minimal<T, InputArchive>::value)> {};
 
  987      #define CEREAL_MAKE_IS_SPECIALIZED_IMPL(name)                                          \ 
  988      template <class T, class A>                                                            \ 
  989      struct is_specialized_##name : std::integral_constant<bool,                            \ 
  990        !std::is_base_of<std::false_type, specialize<A, T, specialization::name>>::value> {} 
  999      #undef CEREAL_MAKE_IS_SPECIALIZED_IMPL 
 1002      template <
class T, 
class A>
 
 1004        is_specialized_member_serialize<T, A>::value +
 
 1005        is_specialized_member_load_save<T, A>::value +
 
 1006        is_specialized_member_load_save_minimal<T, A>::value +
 
 1007        is_specialized_non_member_serialize<T, A>::value +
 
 1008        is_specialized_non_member_load_save<T, A>::value +
 
 1009        is_specialized_non_member_load_save_minimal<T, A>::value> {};
 
 1013    template <
class T, 
class A>
 
 1015      detail::is_specialized_member_serialize<T, A>::value ||
 
 1016      detail::is_specialized_member_load_save<T, A>::value ||
 
 1017      detail::is_specialized_member_load_save_minimal<T, A>::value ||
 
 1018      detail::is_specialized_non_member_serialize<T, A>::value ||
 
 1019      detail::is_specialized_non_member_load_save<T, A>::value ||
 
 1020      detail::is_specialized_non_member_load_save_minimal<T, A>::value>
 
 1028    #define CEREAL_MAKE_IS_SPECIALIZED_ASSERT(name, versioned_name, print_name, spec_name)                      \ 
 1029    static_assert( (is_specialized<T, A>::value && detail::is_specialized_##spec_name<T, A>::value &&           \ 
 1030                   (has_##name<T, A>::value || has_##versioned_name<T, A>::value))                              \ 
 1031                   || !(is_specialized<T, A>::value && detail::is_specialized_##spec_name<T, A>::value),        \ 
 1032                   "cereal detected " #print_name " specialization but no " #print_name " serialize function" )
 
 1037    #define CEREAL_MAKE_IS_SPECIALIZED(name, versioned_name, spec_name)                     \ 
 1038    template <class T, class A>                                                             \ 
 1039    struct is_specialized_##name : std::integral_constant<bool,                             \ 
 1040      is_specialized<T, A>::value && detail::is_specialized_##spec_name<T, A>::value>       \ 
 1041    { CEREAL_MAKE_IS_SPECIALIZED_ASSERT(name, versioned_name, name, spec_name); };          \ 
 1042    template <class T, class A>                                                             \ 
 1043    struct is_specialized_##versioned_name : std::integral_constant<bool,                   \ 
 1044      is_specialized<T, A>::value && detail::is_specialized_##spec_name<T, A>::value>       \ 
 1045    { CEREAL_MAKE_IS_SPECIALIZED_ASSERT(name, versioned_name, versioned_name, spec_name); } 
 1060    #undef CEREAL_MAKE_IS_SPECIALIZED_ASSERT 
 1061    #undef CEREAL_MAKE_IS_SPECIALIZED 
 1065    template <
class T, 
class OutputArchive>
 
 1067      is_specialized_member_save_minimal<T, OutputArchive>::value ||
 
 1068      ((has_member_save_minimal<T, OutputArchive>::value ||
 
 1069        has_non_member_save_minimal<T, OutputArchive>::value ||
 
 1070        has_member_versioned_save_minimal<T, OutputArchive>::value ||
 
 1071        has_non_member_versioned_save_minimal<T, OutputArchive>::value) &&
 
 1072       !(is_specialized_member_serialize<T, OutputArchive>::value ||
 
 1073         is_specialized_member_save<T, OutputArchive>::value))> {};
 
 1077    template <
class T, 
class InputArchive>
 
 1079      is_specialized_member_load_minimal<T, InputArchive>::value ||
 
 1080      ((has_member_load_minimal<T, InputArchive>::value ||
 
 1081        has_non_member_load_minimal<T, InputArchive>::value ||
 
 1082        has_member_versioned_load_minimal<T, InputArchive>::value ||
 
 1083        has_non_member_versioned_load_minimal<T, InputArchive>::value) &&
 
 1084       !(is_specialized_member_serialize<T, InputArchive>::value ||
 
 1085         is_specialized_member_load<T, InputArchive>::value))> {};
 
 1092      template <
class T, 
class OutputArchive>
 
 1094        count_specializations<T, OutputArchive>::value ? count_specializations<T, OutputArchive>::value :
 
 1095        has_member_save<T, OutputArchive>::value +
 
 1096        has_non_member_save<T, OutputArchive>::value +
 
 1097        has_member_serialize<T, OutputArchive>::value +
 
 1098        has_non_member_serialize<T, OutputArchive>::value +
 
 1099        has_member_save_minimal<T, OutputArchive>::value +
 
 1100        has_non_member_save_minimal<T, OutputArchive>::value +
 
 1102        has_member_versioned_save<T, OutputArchive>::value +
 
 1103        has_non_member_versioned_save<T, OutputArchive>::value +
 
 1104        has_member_versioned_serialize<T, OutputArchive>::value +
 
 1105        has_non_member_versioned_serialize<T, OutputArchive>::value +
 
 1106        has_member_versioned_save_minimal<T, OutputArchive>::value +
 
 1107        has_non_member_versioned_save_minimal<T, OutputArchive>::value> {};
 
 1110    template <
class T, 
class OutputArchive>
 
 1112      detail::count_output_serializers<T, OutputArchive>::value == 1> {};
 
 1119      template <
class T, 
class InputArchive>
 
 1121        count_specializations<T, InputArchive>::value ? count_specializations<T, InputArchive>::value :
 
 1122        has_member_load<T, InputArchive>::value +
 
 1123        has_non_member_load<T, InputArchive>::value +
 
 1124        has_member_serialize<T, InputArchive>::value +
 
 1125        has_non_member_serialize<T, InputArchive>::value +
 
 1126        has_member_load_minimal<T, InputArchive>::value +
 
 1127        has_non_member_load_minimal<T, InputArchive>::value +
 
 1129        has_member_versioned_load<T, InputArchive>::value +
 
 1130        has_non_member_versioned_load<T, InputArchive>::value +
 
 1131        has_member_versioned_serialize<T, InputArchive>::value +
 
 1132        has_non_member_versioned_serialize<T, InputArchive>::value +
 
 1133        has_member_versioned_load_minimal<T, InputArchive>::value +
 
 1134        has_non_member_versioned_load_minimal<T, InputArchive>::value> {};
 
 1137    template <
class T, 
class InputArchive>
 
 1139      detail::count_input_serializers<T, InputArchive>::value == 1> {};
 
 1151          hash(std::hash<std::type_index>()(
typeid(T)) ^ (std::hash<void const *>()(t) << 1))
 
 1155          { 
return (type == other.type) && (ptr == other.ptr); }
 
 1157          std::type_index type;
 
 1172      template <
template<
typename> 
class Cast, 
class Base>
 
 1179      template <
class Cast, 
template<
class, 
class> 
class Test, 
class Archive,
 
 1180                bool IsBaseCast = std::is_base_of<BaseCastBase, Cast>::value>
 
 1185      template <
class Cast, 
template<
class, 
class> 
class Test, 
class Archive>
 
 1194    template <
class Cast, 
template<
class, 
class> 
class Test, 
class Archive>
 
 1205        static auto (check)( U 
const & t ) -> 
decltype( ::cereal::access::shared_from_this(t), std::true_type() );
 
 1207        static auto (check)( ... ) -> 
decltype( std::false_type() );
 
 1210        static auto get( U 
const & t ) -> 
decltype( t.shared_from_this() );
 
 1224        using PtrType = 
decltype(detail::shared_from_this_wrapper::get(std::declval<T>()));
 
 1227        using type = 
typename std::decay<typename PtrType::element_type>::type;
 
 1238    template <class T, bool IsCerealMinimalTrait = std::is_base_of<detail::NoConvertBase, T>::value>
 
 1248      using type = 
typename T::type;
 
 1256      #ifdef CEREAL_OLDER_GCC 
 1257      template <
class TT, 
class SFINAE = 
void>
 
 1258      struct test : no {};
 
 1260      struct test<TT, typename detail::Void< decltype( cereal::access::construct<TT>() ) >::type> : yes {};
 
 1261      static const bool value = test<T>();
 
 1264      static auto test(
int) -> 
decltype( cereal::access::construct<TT>(), yes());
 
 1266      static no test(...);
 
 1267      static const bool value = std::is_same<decltype(test<T>(0)), yes>::value;
 
 1276      using decay_archive = 
typename std::decay<typename strip_minimal<A>::type>::type;
 
 1289    template <
class ArchiveT, 
class CerealArchiveT>
 
 1291      std::is_same<detail::decay_archive<ArchiveT>, CerealArchiveT>::value>
 
 1315    #define CEREAL_ARCHIVE_RESTRICT(INTYPE, OUTTYPE) \ 
 1316    typename std::enable_if<cereal::traits::is_same_archive<Archive, INTYPE>::value || cereal::traits::is_same_archive<Archive, OUTTYPE>::value, void>::type 
 1326      std::is_base_of<TextArchive, detail::decay_archive<A>>::value>
 
 1333    template <
class T, 
class A,
 
 1336              bool NonMember = traits::has_non_member_load_and_construct<T, A>::value,
 
 1337              bool NonMemberVersioned = traits::has_non_member_versioned_load_and_construct<T, A>::value>
 
 1341        "cereal found more than one compatible load_and_construct function for the provided type and archive combination. \n\n " 
 1342        "Types must either have a member load_and_construct function or a non-member specialization of LoadAndConstruct (you may not mix these). \n " 
 1343        "In addition, you may not mix versioned with non-versioned load_and_construct functions. \n\n " );
 
 1344      static T * load_andor_construct( A & , 
construct<T> &  )
 
 1349    template <
class T, 
class A>
 
 1353                     "Trying to serialize a an object with no default constructor. \n\n " 
 1354                     "Types must either be default constructible or define either a member or non member Construct function. \n " 
 1355                     "Construct functions generally have the signature: \n\n " 
 1356                     "template <class Archive> \n " 
 1357                     "static void load_and_construct(Archive & ar, cereal::construct<T> & construct) \n " 
 1361                     "  construct( a ); \n " 
 1363      static T * load_andor_construct()
 
 1364      { return ::cereal::access::construct<T>(); }
 
 1368    template <
class T, 
class A>
 
 1373        access::load_and_construct<T>( ar, 
construct );
 
 1378    template <
class T, 
class A>
 
 1383        const auto version = ar.template loadClassVersion<T>();
 
 1384        access::load_and_construct<T>( ar, 
construct, version );
 
 1389    template <
class T, 
class A>
 
 1399    template <
class T, 
class A>
 
 1404        const auto version = ar.template loadClassVersion<T>();
 
Access control and default construction.
 
Used to construct types with no default constructor.
Definition: access.hpp:165
 
Preprocessor macros that can customise the cereal library.
 
#define CEREAL_LOAD_MINIMAL_FUNCTION_NAME
The deserialization (load_minimal) function name to search for.
Definition: macros.hpp:99
 
#define CEREAL_LOAD_FUNCTION_NAME
The deserialization (load) function name to search for.
Definition: macros.hpp:85
 
#define CEREAL_SAVE_MINIMAL_FUNCTION_NAME
The serialization (save_minimal) function name to search for.
Definition: macros.hpp:106
 
#define CEREAL_SERIALIZE_FUNCTION_NAME
The serialization/deserialization function name to search for.
Definition: macros.hpp:78
 
A class that allows cereal to load smart pointers to types that have no default constructor.
Definition: access.hpp:109
 
Definition: traits.hpp:1339
 
Type traits only struct used to mark an archive as human readable (text based)
Definition: traits.hpp:1321
 
A type that can implicitly convert to anything else.
Definition: traits.hpp:655
 
Common base type for base class casting.
Definition: traits.hpp:1167
 
Definition: traits.hpp:82
 
Definition: traits.hpp:79
 
Used to help strip away conversion wrappers.
Definition: traits.hpp:610
 
A struct that prevents implicit conversion.
Definition: traits.hpp:619
 
Source type
Used to get underlying type easily.
Definition: traits.hpp:620
 
A struct that prevents implicit conversion.
Definition: traits.hpp:637
 
Source type
Used to get underlying type easily.
Definition: traits.hpp:638
 
Definition: traits.hpp:1161
 
Definition: traits.hpp:1146
 
The number of output serialization functions available.
Definition: traits.hpp:1107
 
Number of specializations detected.
Definition: traits.hpp:1009
 
Used to delay a static_assert until template instantiation.
Definition: traits.hpp:57
 
Definition: traits.hpp:1170
 
Definition: traits.hpp:888
 
Definition: traits.hpp:893
 
Base class cast, behave as the test.
Definition: traits.hpp:1182
 
Definition: traits.hpp:405
 
Definition: traits.hpp:1203
 
Get the type of the base class of T which inherited from std::enable_shared_from_this.
Definition: traits.hpp:1222
 
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:1227
 
Definition: traits.hpp:971
 
Non member load and construct check.
Definition: traits.hpp:942
 
Member load and construct check.
Definition: traits.hpp:899
 
Definition: traits.hpp:328
 
Definition: traits.hpp:955
 
Member load and construct check (versioned)
Definition: traits.hpp:904
 
Definition: traits.hpp:341
 
Checks to see if the base class used in a cast has a minimal serialization.
Definition: traits.hpp:1196
 
Definition: traits.hpp:1073
 
Definition: traits.hpp:961
 
Determine if T or any base class of T has inherited from std::enable_shared_from_this.
Definition: traits.hpp:1217
 
Determines whether the class T can be default constructed by cereal::access.
Definition: traits.hpp:1255
 
Definition: traits.hpp:414
 
Definition: traits.hpp:1112
 
Checks if the provided archive type is equal to some cereal archive type.
Definition: traits.hpp:1292
 
Check if any specialization exists for a type.
Definition: traits.hpp:1021
 
Checks if an archive is a text archive (human readable)
Definition: traits.hpp:1327
 
Extracts the true type from something possibly wrapped in a cereal NoConvert.
Definition: traits.hpp:1240
 
typename detail::DisableIfHelper< Conditions... >::type DisableIf
Provides a way to disable a function if conditions are met.
Definition: traits.hpp:148
 
#define CEREAL_MAKE_IS_SPECIALIZED_IMPL(name)
Create a test for a cereal::specialization entry.
Definition: traits.hpp:987
 
#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
 
#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
 
#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
 
typename detail::EnableIfHelper< Conditions... >::type EnableIf
Provides a way to enable a function if conditions are met.
Definition: traits.hpp:116
 
#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
 
#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
 
#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
 
#define CEREAL_MAKE_HAS_NON_MEMBER_LOAD_AND_CONSTRUCT_TEST(test_name, versioned)
Creates a test for whether a non-member load_and_construct specialization exists.
Definition: traits.hpp:910
 
#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_VERSIONED_TEST
Used to convert a MAKE_HAS_XXX macro into a versioned variant.
Definition: traits.hpp:178
 
#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:818
 
#define CEREAL_MAKE_HAS_MEMBER_SAVE_MINIMAL_HELPERS_IMPL(test_name, versioned)
Creates helpers for minimal save functions.
Definition: traits.hpp:482
 
sfinae
Return type for SFINAE Enablers.
Definition: traits.hpp:66
 
#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
 
typename std::decay< typename strip_minimal< A >::type >::type decay_archive
Removes all qualifiers and minimal wrappers from an archive.
Definition: traits.hpp:1276
 
#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
 
#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
 
#define CEREAL_MAKE_IS_SPECIALIZED(name, versioned_name, spec_name)
Generates a test for specialization for versioned and unversioned functions.
Definition: traits.hpp:1037