diff --git a/sprout/container/container_transform_traits.hpp b/sprout/container/container_transform_traits.hpp index 0415a65d..326976dd 100644 --- a/sprout/container/container_transform_traits.hpp +++ b/sprout/container/container_transform_traits.hpp @@ -2,6 +2,7 @@ #define SPROUT_CONTAINER_CONTAINER_TRANSFORM_TRAITS_HPP #include +#include #include #include @@ -13,9 +14,33 @@ namespace sprout { struct container_transform_traits; namespace detail { + template + struct is_like_array_class + : public std::false_type + {}; + template< + template class Array, + typename T, + std::size_t N + > + struct is_like_array_class > + : public std::true_type + {}; + template + struct is_like_array_class + : public sprout::detail::is_like_array_class + {}; + template + struct is_like_array_class + : public sprout::detail::is_like_array_class + {}; + template + struct is_like_array_class + : public sprout::detail::is_like_array_class + {}; + template::size_type Size> struct default_array_rebind_size; - template< template class Array, typename T, @@ -26,16 +51,26 @@ namespace sprout { public: typedef Array type; }; + + template + struct inherit_default_rebind_size {}; + template + struct inherit_default_rebind_size< + Container, + typename std::enable_if::value>::type + > { + public: + template::size_type Size> + struct rebind_size + : public sprout::detail::default_array_rebind_size + {}; + }; } // namespace detail template - struct container_transform_traits { - public: - template::size_type Size> - struct rebind_size - : public sprout::detail::default_array_rebind_size - {}; - }; + struct container_transform_traits + : public sprout::detail::inherit_default_rebind_size + {}; template struct container_transform_traits { public: diff --git a/sprout/container/metafunctions.hpp b/sprout/container/metafunctions.hpp index d9a440c6..71d2bedb 100644 --- a/sprout/container/metafunctions.hpp +++ b/sprout/container/metafunctions.hpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include diff --git a/sprout/container/rebind_size.hpp b/sprout/container/rebind_size.hpp index 4b80521a..f872b0d1 100644 --- a/sprout/container/rebind_size.hpp +++ b/sprout/container/rebind_size.hpp @@ -10,10 +10,9 @@ namespace sprout { // rebind_size // template::size_type Size> - struct rebind_size { - public: - typedef typename sprout::container_transform_traits::template rebind_size::type type; - }; + struct rebind_size + : public sprout::container_transform_traits::template rebind_size + {}; } // namespace containers } // namespace sprout diff --git a/sprout/container/weak_rebind_size.hpp b/sprout/container/weak_rebind_size.hpp new file mode 100644 index 00000000..4deda56f --- /dev/null +++ b/sprout/container/weak_rebind_size.hpp @@ -0,0 +1,74 @@ +#ifndef SPROUT_CONTAINER_WEAK_REBIND_SIZE_HPP +#define SPROUT_CONTAINER_WEAK_REBIND_SIZE_HPP + +#include +#include +#include + +namespace sprout { + namespace containers { + namespace detail { + template< + typename T, + template::size_type> class = T::template rebind_size + > + std::true_type sprout_has_xxx_impl_check_template_rebind_size(int); + template + std::false_type sprout_has_xxx_impl_check_template_rebind_size(long); + template + struct has_rebind_size + : decltype(sprout::containers::detail::sprout_has_xxx_impl_check_template_rebind_size(0)) + {}; + } // namespace detail + // + // is_rebindable_size + // + template + struct is_rebindable_size + : public sprout::containers::detail::has_rebind_size< + sprout::container_transform_traits + > + {}; + template + struct is_rebindable_size + : public sprout::containers::is_rebindable_size + {}; + template + struct is_rebindable_size + : public sprout::containers::is_rebindable_size + {}; + template + struct is_rebindable_size + : public sprout::containers::is_rebindable_size + {}; + + namespace detail { + template::size_type Size, typename = void> + struct weak_rebind_size_impl; + template::size_type Size> + struct weak_rebind_size_impl< + Container, Size, + typename std::enable_if::value>::type + > + : public sprout::container_transform_traits::template rebind_size + {}; + template::size_type Size> + struct weak_rebind_size_impl< + Container, Size, + typename std::enable_if::value>::type + > { + public: + typedef Container type; + }; + } // namespace detail + // + // weak_rebind_size + // + template::size_type Size> + struct weak_rebind_size + : public sprout::containers::detail::weak_rebind_size_impl + {}; + } // namespace containers +} // namespace sprout + +#endif // #ifndef SPROUT_CONTAINER_WEAK_REBIND_SIZE_HPP diff --git a/sprout/iterator/bytes_iterator.hpp b/sprout/iterator/bytes_iterator.hpp index 187eedc5..62e37b1c 100644 --- a/sprout/iterator/bytes_iterator.hpp +++ b/sprout/iterator/bytes_iterator.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include namespace sprout { diff --git a/sprout/range/adaptor.hpp b/sprout/range/adaptor.hpp index 886f77f7..2d3e22a5 100644 --- a/sprout/range/adaptor.hpp +++ b/sprout/range/adaptor.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include diff --git a/sprout/range/adaptor/deep_copied.hpp b/sprout/range/adaptor/deep_copied.hpp new file mode 100644 index 00000000..281e9ab8 --- /dev/null +++ b/sprout/range/adaptor/deep_copied.hpp @@ -0,0 +1,36 @@ +#ifndef SPROUT_RANGE_ADAPTOR_DEEP_COPIED_HPP +#define SPROUT_RANGE_ADAPTOR_DEEP_COPIED_HPP + +#include +#include +#include +#include + +namespace sprout { + namespace adaptors { + // + // deep_copied_forwarder + // + class deep_copied_forwarder {}; + + // + // deep_copied + // + namespace { + SPROUT_STATIC_CONSTEXPR sprout::adaptors::deep_copied_forwarder deep_copied{}; + } // anonymous-namespace + + // + // operator| + // + template + inline SPROUT_CONSTEXPR typename sprout::container_construct_traits< + typename std::remove_reference::type + >::copied_type + operator|(Range&& lhs, sprout::adaptors::deep_copied_forwarder const& rhs) { + return sprout::deep_copy(sprout::forward(lhs)); + } + } // namespace adaptors +} // namespace sprout + +#endif // #ifndef SPROUT_RANGE_ADAPTOR_DEEP_COPIED_HPP diff --git a/sprout/range/adaptor/sized.hpp b/sprout/range/adaptor/sized.hpp index 4caaec08..c19d6a5f 100644 --- a/sprout/range/adaptor/sized.hpp +++ b/sprout/range/adaptor/sized.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -80,7 +81,8 @@ namespace sprout { explicit SPROUT_CONSTEXPR sized_range(range_type& range) : base_type( sprout::begin(range), - sized_impl_type::static_size < sprout::size(range) + sized_impl_type::static_size + < static_cast::size_type>(sprout::size(range)) ? sprout::next(sprout::begin(range), sized_impl_type::static_size) : sprout::end(range) ) @@ -126,8 +128,13 @@ namespace sprout { // template::size_type Size> struct container_construct_traits > { + private: + typedef typename sprout::container_construct_traits::copied_type range_copied_type; public: - typedef typename sprout::container_construct_traits::copied_type copied_type; + typedef typename sprout::containers::weak_rebind_size< + range_copied_type, + sprout::adaptors::sized_range::static_size + >::type copied_type; public: template static SPROUT_CONSTEXPR copied_type deep_copy(Cont&& cont) { diff --git a/sprout/type_traits/has_xxx.hpp b/sprout/type_traits/has_xxx.hpp index b083b116..bcfabc63 100644 --- a/sprout/type_traits/has_xxx.hpp +++ b/sprout/type_traits/has_xxx.hpp @@ -9,7 +9,7 @@ // SPROUT_HAS_XXX_TYPE_DEF // #define SPROUT_HAS_XXX_TYPE_DEF(NAME, TYPE) \ - template \ + template \ std::true_type SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_type_, TYPE), __LINE__)(int); \ template \ std::false_type SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_type_, TYPE), __LINE__)(long); \ diff --git a/testspr/print.hpp b/testspr/print.hpp index ad50662e..c4f516eb 100644 --- a/testspr/print.hpp +++ b/testspr/print.hpp @@ -6,6 +6,7 @@ #include #include #include +#include namespace testspr { // @@ -37,6 +38,14 @@ namespace testspr { testspr::print_ln(std::bitset(t).template to_string()); } + // + // print_typename + // + template + void print_typename() { + testspr::print_ln(testspr::typename_of()); + } + // // print_hl //