diff --git a/libs/optional/test/optional.cpp b/libs/optional/test/optional.cpp index abe89404..d2f0c3f3 100644 --- a/libs/optional/test/optional.cpp +++ b/libs/optional/test/optional.cpp @@ -304,7 +304,6 @@ namespace testspr { TESTSPR_ASSERT(!opt3); } - // get TESTSPR_BOTH_ASSERT(sprout::get(opt1) == 1234); { diff --git a/libs/tuple/test/tuple.cpp b/libs/tuple/test/tuple.cpp new file mode 100644 index 00000000..e6844d55 --- /dev/null +++ b/libs/tuple/test/tuple.cpp @@ -0,0 +1,235 @@ +#ifndef SPROUT_LIBS_TUPLE_TEST_TUPLE_CPP +#define SPROUT_LIBS_TUPLE_TEST_TUPLE_CPP + +#include +#include +#include + +namespace testspr { + static void tuple_test() { + using namespace sprout; + { + SPROUT_STATIC_CONSTEXPR auto tup1 = sprout::tuples::tuple(1, 1.0); + SPROUT_STATIC_CONSTEXPR auto tup2 = sprout::tuples::tuple(); + + // constructor + { + SPROUT_STATIC_CONSTEXPR auto tup3 = sprout::tuples::tuple(); + TESTSPR_BOTH_ASSERT(sprout::tuples::get<0>(tup3) == 0); + TESTSPR_BOTH_ASSERT(sprout::tuples::get<1>(tup3) == 0.0); + } + { + SPROUT_STATIC_CONSTEXPR auto tup3 = sprout::tuples::tuple(tup1); + TESTSPR_BOTH_ASSERT(sprout::tuples::get<0>(tup3) == 1); + TESTSPR_BOTH_ASSERT(sprout::tuples::get<1>(tup3) == 1.0); + } + { + SPROUT_STATIC_CONSTEXPR auto tup3 = sprout::tuples::tuple(1, 1.0); + TESTSPR_BOTH_ASSERT(sprout::tuples::get<0>(tup3) == 1); + TESTSPR_BOTH_ASSERT(sprout::tuples::get<1>(tup3) == 1.0); + } + + { + SPROUT_STATIC_CONSTEXPR auto tup3 = sprout::tuples::tuple(1l); + TESTSPR_BOTH_ASSERT(sprout::tuples::get<0>(tup3) == 1); + TESTSPR_BOTH_ASSERT(sprout::tuples::get<1>(tup3) == 0.0); + } + { + SPROUT_STATIC_CONSTEXPR auto tup3 = sprout::tuples::tuple(1l, 1.0f); + TESTSPR_BOTH_ASSERT(sprout::tuples::get<0>(tup3) == 1); + TESTSPR_BOTH_ASSERT(sprout::tuples::get<1>(tup3) == 1.0); + } + { + SPROUT_STATIC_CONSTEXPR auto tup3 = sprout::tuples::tuple(1l, 1.0f, '-'); + TESTSPR_BOTH_ASSERT(sprout::tuples::get<0>(tup3) == 1); + TESTSPR_BOTH_ASSERT(sprout::tuples::get<1>(tup3) == 1.0); + } + + { + SPROUT_STATIC_CONSTEXPR auto tup3 = sprout::tuples::tuple(sprout::tuples::tuple(1l)); + TESTSPR_BOTH_ASSERT(sprout::tuples::get<0>(tup3) == 1); + TESTSPR_BOTH_ASSERT(sprout::tuples::get<1>(tup3) == 0.0); + } + { + SPROUT_STATIC_CONSTEXPR auto tup3 = sprout::tuples::tuple(sprout::tuples::tuple(1l, 1.0f)); + TESTSPR_BOTH_ASSERT(sprout::tuples::get<0>(tup3) == 1); + TESTSPR_BOTH_ASSERT(sprout::tuples::get<1>(tup3) == 1.0); + } + { + SPROUT_STATIC_CONSTEXPR auto tup3 = sprout::tuples::tuple(sprout::tuples::tuple(1l, 1.0f, '-')); + TESTSPR_BOTH_ASSERT(sprout::tuples::get<0>(tup3) == 1); + TESTSPR_BOTH_ASSERT(sprout::tuples::get<1>(tup3) == 1.0); + } + + // operator= + { + auto tup3 = tup2; + tup3 = sprout::tuples::tuple(1, 1.0); + TESTSPR_ASSERT(sprout::tuples::get<0>(tup3) == 1); + TESTSPR_ASSERT(sprout::tuples::get<1>(tup3) == 1.0); + } + { + auto tup3 = tup2; + tup3 = sprout::tuples::tuple(1l); + TESTSPR_ASSERT(sprout::tuples::get<0>(tup3) == 1); + TESTSPR_ASSERT(sprout::tuples::get<1>(tup3) == 0.0); + } + { + auto tup3 = tup2; + tup3 = sprout::tuples::tuple(1l, 1.0f); + TESTSPR_ASSERT(sprout::tuples::get<0>(tup3) == 1); + TESTSPR_ASSERT(sprout::tuples::get<1>(tup3) == 1.0); + } + { + auto tup3 = tup2; + tup3 = sprout::tuples::tuple(1l, 1.0f, '-'); + TESTSPR_ASSERT(sprout::tuples::get<0>(tup3) == 1); + TESTSPR_ASSERT(sprout::tuples::get<1>(tup3) == 1.0); + } + + // swap + { + auto tup3 = tup1; + auto tup4 = tup2; + tup3.swap(tup4); + TESTSPR_ASSERT(sprout::tuples::get<0>(tup3) == 0); + TESTSPR_ASSERT(sprout::tuples::get<1>(tup3) == 0.0); + TESTSPR_ASSERT(sprout::tuples::get<0>(tup4) == 1); + TESTSPR_ASSERT(sprout::tuples::get<1>(tup4) == 1.0); + } + { + auto tup3 = tup1; + auto tup4 = tup2; + swap(tup3, tup4); + TESTSPR_ASSERT(sprout::tuples::get<0>(tup3) == 0); + TESTSPR_ASSERT(sprout::tuples::get<1>(tup3) == 0.0); + TESTSPR_ASSERT(sprout::tuples::get<0>(tup4) == 1); + TESTSPR_ASSERT(sprout::tuples::get<1>(tup4) == 1.0); + } + + // std::tuple_size + TESTSPR_BOTH_ASSERT(std::tuple_size::value == 2); + + // std::tuple_element + TESTSPR_BOTH_ASSERT((std::is_same::type, int const>::value)); + TESTSPR_BOTH_ASSERT((std::is_same::type, double const>::value)); + + // operator== + TESTSPR_BOTH_ASSERT(!(tup1 == tup2)); + TESTSPR_BOTH_ASSERT((tup1 == sprout::tuples::tuple(1, 1.0))); + TESTSPR_BOTH_ASSERT((!(tup1 == sprout::tuples::tuple()))); + TESTSPR_BOTH_ASSERT((tup1 == sprout::tuples::tuple(1l, 1.0f))); + + // operator!= + TESTSPR_BOTH_ASSERT(tup1 != tup2); + TESTSPR_BOTH_ASSERT((!(tup1 != sprout::tuples::tuple(1, 1.0)))); + TESTSPR_BOTH_ASSERT((tup1 != sprout::tuples::tuple())); + TESTSPR_BOTH_ASSERT((!(tup1 != sprout::tuples::tuple(1l, 1.0f)))); + + // operator< + TESTSPR_BOTH_ASSERT(!(tup1 < tup2)); + TESTSPR_BOTH_ASSERT((!(tup1 < sprout::tuples::tuple(1, -1.0)))); + TESTSPR_BOTH_ASSERT((!(tup1 < sprout::tuples::tuple(1, 1.0)))); + TESTSPR_BOTH_ASSERT((tup1 < sprout::tuples::tuple(1, 2.0))); + TESTSPR_BOTH_ASSERT((!(tup1 < sprout::tuples::tuple()))); + TESTSPR_BOTH_ASSERT((!(tup1 < sprout::tuples::tuple(1l, -1.0f)))); + TESTSPR_BOTH_ASSERT((!(tup1 < sprout::tuples::tuple(1l, 1.0f)))); + TESTSPR_BOTH_ASSERT((tup1 < sprout::tuples::tuple(1l, 2.0f))); + + // operator> + TESTSPR_BOTH_ASSERT(tup1 > tup2); + TESTSPR_BOTH_ASSERT((tup1 > sprout::tuples::tuple(1, -1.0))); + TESTSPR_BOTH_ASSERT((!(tup1 > sprout::tuples::tuple(1, 1.0)))); + TESTSPR_BOTH_ASSERT((!(tup1 > sprout::tuples::tuple(1, 2.0)))); + TESTSPR_BOTH_ASSERT((tup1 > sprout::tuples::tuple())); + TESTSPR_BOTH_ASSERT((tup1 > sprout::tuples::tuple(1l, -1.0f))); + TESTSPR_BOTH_ASSERT((!(tup1 > sprout::tuples::tuple(1l, 1.0f)))); + TESTSPR_BOTH_ASSERT((!(tup1 > sprout::tuples::tuple(1l, 2.0f)))); + + // operator<= + TESTSPR_BOTH_ASSERT(!(tup1 <= tup2)); + TESTSPR_BOTH_ASSERT((!(tup1 <= sprout::tuples::tuple(1, -1.0)))); + TESTSPR_BOTH_ASSERT((tup1 <= sprout::tuples::tuple(1, 1.0))); + TESTSPR_BOTH_ASSERT((tup1 <= sprout::tuples::tuple(1, 2.0))); + TESTSPR_BOTH_ASSERT((!(tup1 <= sprout::tuples::tuple()))); + TESTSPR_BOTH_ASSERT((!(tup1 <= sprout::tuples::tuple(1l, -1.0f)))); + TESTSPR_BOTH_ASSERT((tup1 <= sprout::tuples::tuple(1l, 1.0f))); + TESTSPR_BOTH_ASSERT((tup1 <= sprout::tuples::tuple(1l, 2.0f))); + + // operator>= + TESTSPR_BOTH_ASSERT(tup1 >= tup2); + TESTSPR_BOTH_ASSERT((tup1 >= sprout::tuples::tuple(1, -1.0))); + TESTSPR_BOTH_ASSERT((tup1 >= sprout::tuples::tuple(1, 1.0))); + TESTSPR_BOTH_ASSERT((!(tup1 >= sprout::tuples::tuple(1, 2.0)))); + TESTSPR_BOTH_ASSERT((tup1 >= sprout::tuples::tuple())); + TESTSPR_BOTH_ASSERT((tup1 >= sprout::tuples::tuple(1l, -1.0f))); + TESTSPR_BOTH_ASSERT((tup1 >= sprout::tuples::tuple(1l, 1.0f))); + TESTSPR_BOTH_ASSERT((!(tup1 >= sprout::tuples::tuple(1l, 2.0f)))); + + // get + TESTSPR_BOTH_ASSERT(sprout::tuples::get<0>(tup1) == 1); + TESTSPR_BOTH_ASSERT(sprout::tuples::get<1>(tup1) == 1.0); + { + auto tup3 = tup1; + TESTSPR_ASSERT(sprout::tuples::get<0>(tup3) == 1); + TESTSPR_ASSERT(sprout::tuples::get<1>(tup3) == 1.0); + } + + // tuple_size + TESTSPR_BOTH_ASSERT(sprout::tuples::tuple_size::value == 2); + + // tuple_element + TESTSPR_BOTH_ASSERT((std::is_same::type, int const>::value)); + TESTSPR_BOTH_ASSERT((std::is_same::type, double const>::value)); + + // make_tuple + TESTSPR_BOTH_ASSERT(sprout::tuples::make_tuple(1, 1.0) == tup1); + + // forward_as_tuple + TESTSPR_BOTH_ASSERT(sprout::tuples::forward_as_tuple(1, 1.0) == tup1); + + // tie + { + auto v1 = 0; + auto v2 = 0.0; + TESTSPR_ASSERT(sprout::tuples::tie(v1, v2) == tup2); + + sprout::tuples::tie(v1, v2) = tup1; + TESTSPR_ASSERT(v1 == 1); + TESTSPR_ASSERT(v2 == 1.0); + } + + // tuple_cat + { + typedef sprout::tuples::result_of::tuple_cat::type concatenated_type; + TESTSPR_BOTH_ASSERT(sprout::tuples::tuple_size::value == 4); + TESTSPR_BOTH_ASSERT((std::is_same::type, int>::value)); + TESTSPR_BOTH_ASSERT((std::is_same::type, double>::value)); + TESTSPR_BOTH_ASSERT((std::is_same::type, int>::value)); + TESTSPR_BOTH_ASSERT((std::is_same::type, double>::value)); + } + + { + SPROUT_STATIC_CONSTEXPR auto tup3 = sprout::tuples::tuple_cat(tup1, tup2); + TESTSPR_BOTH_ASSERT(sprout::tuples::get<0>(tup3) == 1); + TESTSPR_BOTH_ASSERT(sprout::tuples::get<1>(tup3) == 1.0); + TESTSPR_BOTH_ASSERT(sprout::tuples::get<2>(tup3) == 0); + TESTSPR_BOTH_ASSERT(sprout::tuples::get<3>(tup3) == 0.0); + } + + // is_tuple + TESTSPR_BOTH_ASSERT(sprout::tuples::is_tuple::value); + TESTSPR_BOTH_ASSERT(!sprout::tuples::is_tuple::value); + + // hash_value + TESTSPR_BOTH_ASSERT((sprout::hash_value(sprout::tuples::tuple(1, 2)) != 0)); + } + } +} // namespace testspr + +#ifndef TESTSPR_CPP_INCLUDE +# define TESTSPR_TEST_FUNCTION testspr::tuple_test +# include +#endif + +#endif // #ifndef SPROUT_LIBS_TUPLE_TEST_TUPLE_CPP diff --git a/sprout/tuple/tuple.hpp b/sprout/tuple/tuple.hpp index 86316466..337fac46 100644 --- a/sprout/tuple/tuple.hpp +++ b/sprout/tuple/tuple.hpp @@ -4,10 +4,10 @@ #include #include #include +#include #include #include #include -#include #include #include diff --git a/sprout/tuple/tuple/get.hpp b/sprout/tuple/tuple/get.hpp index 75efddb6..674ecafe 100644 --- a/sprout/tuple/tuple/get.hpp +++ b/sprout/tuple/tuple/get.hpp @@ -40,17 +40,26 @@ namespace sprout { : public std::tuple_element {}; template - struct tuple_element - : public sprout::tuples::tuple_element - {}; + struct tuple_element { + public: + typedef typename std::add_const< + typename sprout::tuples::tuple_element::type + >::type type; + }; template - struct tuple_element - : public sprout::tuples::tuple_element - {}; + struct tuple_element { + public: + typedef typename std::add_volatile< + typename sprout::tuples::tuple_element::type + >::type type; + }; template - struct tuple_element - : public sprout::tuples::tuple_element - {}; + struct tuple_element { + public: + typedef typename std::add_cv< + typename sprout::tuples::tuple_element::type + >::type type; + }; namespace detail { template diff --git a/sprout/tuple/tuple/make_tuple.hpp b/sprout/tuple/tuple/make_tuple.hpp index 30f2491e..7dd9b1dd 100644 --- a/sprout/tuple/tuple/make_tuple.hpp +++ b/sprout/tuple/tuple/make_tuple.hpp @@ -14,7 +14,8 @@ namespace sprout { // make_tuple // template - inline SPROUT_CONSTEXPR sprout::tuples::tuple::type...> make_tuple(Types&&... args) { + inline SPROUT_CONSTEXPR sprout::tuples::tuple::type...> + make_tuple(Types&&... args) { return sprout::tuples::tuple::type...>(sprout::forward(args)...); } @@ -22,7 +23,8 @@ namespace sprout { // forward_as_tuple // template - inline SPROUT_CONSTEXPR sprout::tuples::tuple forward_as_tuple(Types&&... args) SPROUT_NOEXCEPT { + inline SPROUT_CONSTEXPR sprout::tuples::tuple + forward_as_tuple(Types&&... args) SPROUT_NOEXCEPT { return sprout::tuples::tuple(sprout::forward(args)...); } @@ -30,7 +32,8 @@ namespace sprout { // tie // template - inline sprout::tuples::tuple tie(Types&... args) SPROUT_NOEXCEPT { + inline sprout::tuples::tuple + tie(Types&... args) SPROUT_NOEXCEPT { return sprout::tuples::tuple(args...); } @@ -86,7 +89,7 @@ namespace sprout { template struct tuple_cat : public sprout::tuples::result_of::detail::tuple_cat_impl< - typename std::remove_reference::type... + typename std::decay::type... > {}; } // namespace result_of @@ -109,23 +112,6 @@ namespace sprout { template struct tuple_cat_impl; - template - struct tuple_cat_impl, Head, Tail...> { - public: - template - static SPROUT_CONSTEXPR Result - call(Head&& head, Tail&&... tail, Args&&... args) { - return sprout::tuples::detail::tuple_cat_impl< - Result, - typename sprout::tuples::detail::tuple_cat_1st_indexes::type, - Tail... - >::call( - sprout::forward(tail)..., - sprout::forward(args)..., - sprout::tuples::get(sprout::forward(head))... - ); - } - }; template struct tuple_cat_impl > { public: @@ -135,6 +121,22 @@ namespace sprout { return Result(sprout::forward(args)...); } }; + template + struct tuple_cat_impl, Head, Tail...> { + public: + template + static SPROUT_CONSTEXPR Result + call(T&& t, Args&&... args) { + return sprout::tuples::detail::tuple_cat_impl< + Result, + typename sprout::tuples::detail::tuple_cat_1st_indexes::type, + Tail... + >::call( + sprout::forward(args)..., + sprout::tuples::get(sprout::forward(t))... + ); + } + }; } // namespace detail // // tuple_cat diff --git a/sprout/tuple/tuple/tuple.hpp b/sprout/tuple/tuple/tuple.hpp index b7d0271d..2b003497 100644 --- a/sprout/tuple/tuple/tuple.hpp +++ b/sprout/tuple/tuple/tuple.hpp @@ -93,6 +93,8 @@ namespace sprout { template class tuple_impl { public: + template + friend class tuple; template friend class sprout::tuples::detail::tuple_impl; protected: @@ -124,6 +126,8 @@ namespace sprout { , private sprout::tuples::detail::head_base::value> { public: + template + friend class tuple; template friend class sprout::tuples::detail::tuple_impl; public: @@ -142,11 +146,11 @@ namespace sprout { static SPROUT_CONSTEXPR inherited_type const& tail(tuple_impl const& t) SPROUT_NOEXCEPT { return t; } - protected: + public: void swap(tuple_impl& t) SPROUT_NOEXCEPT_EXPR( - SPROUT_NOEXCEPT_EXPR(sprout::swap(head(std::declval()), head(t))) - && SPROUT_NOEXCEPT_EXPR(inherited_type::swap(tail(t))) + SPROUT_NOEXCEPT_EXPR(sprout::swap(head(std::declval()), head(t))) + && SPROUT_NOEXCEPT_EXPR(std::declval().swap(tail(t))) ) { sprout::swap(head(*this), head(t)); @@ -223,52 +227,6 @@ namespace sprout { return *this; } }; - - template - struct and_impl; - template<> - struct and_impl - : public std::true_type - {}; - template<> - struct and_impl - : public std::false_type - {}; - template - struct and_impl - : public std::integral_constant::value> - {}; - template - struct and_impl - : public std::false_type - {}; - template - struct and_ - : public sprout::tuples::detail::and_impl - {}; - - template - struct or_impl; - template<> - struct or_impl - : public std::true_type - {}; - template<> - struct or_impl - : public std::false_type - {}; - template - struct or_impl - : public std::true_type - {}; - template - struct or_impl - : public std::integral_constant::value> - {}; - template - struct or_ - : public sprout::tuples::detail::and_impl - {}; } // namespace detail // @@ -278,7 +236,7 @@ namespace sprout { class tuple : public sprout::tuples::detail::tuple_impl<0, Types...> { - public: + private: typedef sprout::tuples::detail::tuple_impl<0, Types...> inherited_type; public: // tuple construction @@ -338,7 +296,7 @@ namespace sprout { } // tuple swap void swap(tuple& other) - SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(inherited_type::swap(other))) + SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(std::declval().swap(other))) { inherited_type::swap(other); } diff --git a/testspr/print.hpp b/testspr/print.hpp index c4f516eb..7e7666ad 100644 --- a/testspr/print.hpp +++ b/testspr/print.hpp @@ -46,6 +46,14 @@ namespace testspr { testspr::print_ln(testspr::typename_of()); } + // + // print_type + // + template + void print_type() { + testspr::print_typename >(); + } + // // print_hl // diff --git a/testspr/sprout.cpp b/testspr/sprout.cpp index 57639832..ca5e9baa 100644 --- a/testspr/sprout.cpp +++ b/testspr/sprout.cpp @@ -9,6 +9,7 @@ #include "../libs/array/test/array.cpp" #include "../libs/string/test/string.cpp" #include "../libs/bitset/test/bitset.cpp" +#include "../libs/tuple/test/tuple.cpp" #include "../libs/optional/test/optional.cpp" #include "../libs/algorithm/test/algorithm.cpp" #include "../libs/random/test/random.cpp" @@ -22,6 +23,7 @@ namespace testspr { testspr::array_test(); testspr::string_test(); testspr::bitset_test(); + testspr::tuple_test(); testspr::optional_test(); testspr::algorithm_test(); testspr::random_test(); diff --git a/testspr/tools.hpp b/testspr/tools.hpp index e6e71663..3670c92d 100644 --- a/testspr/tools.hpp +++ b/testspr/tools.hpp @@ -45,6 +45,15 @@ #endif // #ifndef SPROUT_CONFIG_DISABLE_CONSTEXPR namespace testspr { + // + // do_nothing + // + template + inline SPROUT_CONSTEXPR bool + do_nothing(T const&) SPROUT_NOEXCEPT { + return true; + } + // // is_even // @@ -226,7 +235,7 @@ namespace testspr { // distance // template - SPROUT_CONSTEXPR typename std::iterator_traits::difference_type + inline SPROUT_CONSTEXPR typename std::iterator_traits::difference_type distance(InputIterator first, InputIterator last) { return first == last ? 0 : 1 + testspr::distance(first + 1, last) @@ -246,7 +255,7 @@ namespace testspr { ; } template - SPROUT_CONSTEXPR bool + inline SPROUT_CONSTEXPR bool equal(Range1 const& range1, Range2 const& range2) { return testspr::equal(sprout::begin(range1), sprout::end(range1), sprout::begin(range2), sprout::end(range2)); } @@ -255,7 +264,7 @@ namespace testspr { // is_found // template - SPROUT_CONSTEXPR bool + inline SPROUT_CONSTEXPR bool is_found(InputIterator first, InputIterator last, T const& value) { return first == last ? false : *first == value ? true @@ -263,7 +272,7 @@ namespace testspr { ; } template - SPROUT_CONSTEXPR bool + inline SPROUT_CONSTEXPR bool is_found(Range const& range, T const& value) { return testspr::is_found(sprout::begin(range), sprout::end(range), value); } @@ -272,21 +281,21 @@ namespace testspr { // count // template - SPROUT_CONSTEXPR typename std::iterator_traits::difference_type + inline SPROUT_CONSTEXPR typename std::iterator_traits::difference_type count(InputIterator first, InputIterator last, T const& value) { return first == last ? 0 : (*first == value ? 1 : 0) + testspr::count(first + 1, last, value) ; } template - SPROUT_CONSTEXPR typename std::iterator_traits::difference_type + inline SPROUT_CONSTEXPR typename std::iterator_traits::difference_type count(Range const& range, T const& value) { return testspr::count(sprout::begin(range), sprout::end(range), value); } namespace detail { template - SPROUT_CONSTEXPR bool + inline SPROUT_CONSTEXPR bool is_permutation_impl( ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, @@ -304,7 +313,7 @@ namespace testspr { // is_permutation // template - SPROUT_CONSTEXPR bool + inline SPROUT_CONSTEXPR bool is_permutation( ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2 @@ -313,7 +322,7 @@ namespace testspr { return testspr::detail::is_permutation_impl(first1, last1, first2, last2, first1, first2); } template - SPROUT_CONSTEXPR bool + inline SPROUT_CONSTEXPR bool is_permutation(Range1 const& range1, Range2 const& range2) { return testspr::is_permutation( sprout::begin(range1), sprout::end(range1), diff --git a/testspr/typeinfo.hpp b/testspr/typeinfo.hpp index e7f3537a..33996f8a 100644 --- a/testspr/typeinfo.hpp +++ b/testspr/typeinfo.hpp @@ -11,6 +11,15 @@ #endif namespace testspr { + // + // id + // + template + struct id { + public: + typedef T type; + }; + // // typename_of //