From e00a74ccfc53cc071d4875882ad80a3cff828608 Mon Sep 17 00:00:00 2001 From: Shane Date: Sun, 14 Jul 2013 22:41:56 -0700 Subject: [PATCH] traits nearly done, looking good so far --- include/cereal/access.hpp | 4 + include/cereal/details/traits.hpp | 204 ++++++++++++------------------ sandbox_vs2012.cpp | 37 ++++-- 3 files changed, 108 insertions(+), 137 deletions(-) diff --git a/include/cereal/access.hpp b/include/cereal/access.hpp index cb5f6022..fdf4b967 100644 --- a/include/cereal/access.hpp +++ b/include/cereal/access.hpp @@ -117,6 +117,10 @@ namespace cereal static auto member_save(Archive & ar, T const & t) -> decltype(t.save(ar)) { t.save(ar); } + template inline + static auto member_save_non_const(Archive & ar, T & t) -> decltype(t.save(ar)) + { t.save(ar); } + template inline static auto member_load(Archive & ar, T & t) -> decltype(t.load(ar)) { t.load(ar); } diff --git a/include/cereal/details/traits.hpp b/include/cereal/details/traits.hpp index 961a7eef..04a479c4 100644 --- a/include/cereal/details/traits.hpp +++ b/include/cereal/details/traits.hpp @@ -43,21 +43,8 @@ namespace cereal typedef std::true_type yes; typedef std::false_type no; - //namespace - //{ - // //! Tests whether a type has a const member save function - // template - // struct has_const_member_save_impl - // { - // template - // static auto test(int) -> decltype( cereal::access::member_save( std::declval(), std::declval() ) == 1, yes()); - // static no test(...); - // static const bool value = std::is_same(0)), yes>::value; - // }; - //} // end anon namespace - //template - //struct has_const_member_save : std::integral_constant::value> {}; + ////! Tests whether a type has a non const member save function //namespace @@ -177,123 +164,92 @@ namespace cereal // ###################################################################### // Non Member Load CEREAL_MAKE_HAS_NON_MEMBER_TEST(load); + + // ###################################################################### + // Member Save + namespace detail + { + template + struct has_member_save_impl + { + template + static auto test(int) -> decltype( cereal::access::member_save( std::declval(), std::declval() ) == 1, yes()); + template + static no test(...); + static const bool value = std::is_same(0)), yes>::value; + + template + static auto test2(int) -> decltype( cereal::access::member_save_non_const( std::declval(), std::declval::type&>() ) == 1, yes()); + template + static no test2(...); + static const bool not_const_type = std::is_same(0)), yes>::value; + }; + } // end namespace detail - // // ###################################################################### - // // Member Load - // template - // struct has_member_load: std::false_type {}; + template + struct has_member_save : std::integral_constant::value> + { + typedef typename detail::has_member_save_impl check; + static_assert( check::value || !check::not_const_type, + "cereal detected a non-const save.\n" + "save member functions must always be const" ); + }; - // template - // struct has_member_load< T, A, - // typename Void< - // decltype( access::member_load(std::declval(), std::declval() ) ) - // >::type - // >: std::true_type {}; + // ###################################################################### + // Non-const Member Save + namespace detail + { + template + struct has_non_member_save_impl + { + template + static auto test(int) -> decltype( save( std::declval(), std::declval() ) == 1, yes()); + template + static no test(...); + static const bool value = std::is_same(0)), yes>::value; + + template + static auto test2(int) -> decltype( save( std::declval(), std::declval::type&>() ) == 1, yes()); + template + static no test2(...); + static const bool not_const_type = std::is_same(0)), yes>::value; + }; + } // end namespace detail - // // ###################################################################### - // // Non Member Load - // char & load(...); - // template - // bool constexpr has_non_member_load() - // { return std::is_void(), std::declval()))>::value; }; + template + struct has_non_member_save : std::integral_constant::value> + { + typedef typename detail::has_non_member_save_impl check; + static_assert( check::value || !check::not_const_type, + "cereal detected a non-const type parameter in non-member save.\n" + "save non-member functions must always pass their types as const" ); + }; - // // ###################################################################### - // // Member Save - // template - // struct has_member_save: std::false_type {}; + // ###################################################################### + template + struct has_member_split : std::integral_constant::value && has_member_save::value> {}; - // template - // struct has_member_save< T, A, - // typename Void< - // decltype( access::member_save(std::declval(), std::declval() ) ) - // >::type - // >: std::true_type {}; + // ###################################################################### + template + struct has_non_member_split : std::integral_constant::value && has_non_member_save::value> {}; - // // ###################################################################### - // // Non-const Member Save - // namespace detail - // { - // // Detection of any (const or non const) member save - // template - // struct has_member_save_any: std::false_type {}; + // ###################################################################### + template + struct is_output_serializable : std::integral_constant::value ^ + has_non_member_save::value ^ + has_member_serialize::value ^ + has_non_member_serialize::value> {}; - // template - // struct has_member_save_any< T, A, - // typename Void< - // decltype( access::non_const_member_save(std::declval(), std::declval::type &>() ) ) - // >::type - // >: std::true_type {}; - // } - - // // Returns true if we detect a member save function that is not const - // template - // constexpr bool is_non_const_member_save() - // { - // return !has_member_save() && detail::has_member_save_any(); - // } - - // // ###################################################################### - // // Non Member Save - // char & save(...); - // template - // bool constexpr has_non_member_save() - // { return std::is_void(), std::declval()))>::value; } - - // // ###################################################################### - // // Non-const Non member Save - // namespace detail - // { - // template - // bool constexpr has_non_member_save_any() - // { return std::is_void(), std::declval::type &>()))>::value; } - // } - - // // Returns true if we detect a non-member save function that is not const - // template - // bool constexpr is_non_const_non_member_save() - // { return !has_non_member_save() && detail::has_non_member_save_any(); } - - // // ###################################################################### - // // Returns true if we have an invalid save function (non const) - // template - // bool constexpr has_non_const_save() - // { return is_non_const_member_save() || is_non_const_non_member_save(); } - - // // ###################################################################### - // template - // constexpr bool has_member_split() - // { return has_member_load() && has_member_save(); } - - // // ###################################################################### - // template - // constexpr bool has_non_member_split() - // { return has_non_member_load() && has_non_member_save(); } - - // // ###################################################################### - // template - // constexpr bool is_output_serializable() - // { - // static_assert( !has_non_const_save(), - // "cereal detected a non const save. \n " - // "save functions must either be const member functions or accept const type aguments if non-member" ); - - // return - // has_member_save() ^ - // has_non_member_save() ^ - // has_member_serialize() ^ - // has_non_member_serialize(); - // } - - // // ###################################################################### - // template - // constexpr bool is_input_serializable() - // { - // return - // has_member_load() ^ - // has_non_member_load() ^ - // has_member_serialize() ^ - // has_non_member_serialize(); - // } + // ###################################################################### + template + struct is_input_serializable : std::integral_constant::value ^ + has_non_member_load::value ^ + has_member_serialize::value ^ + has_non_member_serialize::value> {}; // // ###################################################################### diff --git a/sandbox_vs2012.cpp b/sandbox_vs2012.cpp index 97bbc433..27c2b523 100644 --- a/sandbox_vs2012.cpp +++ b/sandbox_vs2012.cpp @@ -39,21 +39,19 @@ template void load( Archive & ar, Test & t ) { } -//namespace cereal -//{ -// template <> -// struct LoadAndAllocate -// { -// template -// static Test * load_and_allocate( Archive & ar ) -// { } -// }; -//} +template +void save( Archive & ar, Test const & t ) +{ } -template -void bla( T & t ) +namespace cereal { - t = 4; + template <> + struct LoadAndAllocate + { + template + static Test * load_and_allocate( Archive & ar ) + { } + }; } int main() @@ -75,6 +73,19 @@ int main() std::cout << "\tload" << std::endl; std::cout << cereal::traits::has_member_load::value << std::endl; std::cout << cereal::traits::has_non_member_load::value << std::endl; + + // save + std::cout << "\tsave" << std::endl; + std::cout << cereal::traits::has_member_save::value << std::endl; + std::cout << cereal::traits::has_non_member_save::value << std::endl; + + // member split + std::cout << "\tmember split" << std::endl; + std::cout << cereal::traits::has_member_split::value << std::endl; + + // serialiable + std::cout << "\toutput serializable" << std::endl; + std::cout << cereal::traits::is_output_serializable::value << std::endl; return 0; } \ No newline at end of file