diff --git a/sprout/container/container_traits.hpp b/sprout/container/container_traits.hpp index f9721831..3236cb8a 100644 --- a/sprout/container/container_traits.hpp +++ b/sprout/container/container_traits.hpp @@ -2,6 +2,7 @@ #define SPROUT_CONTAINER_CONTAINER_TRAITS_HPP #include +#include #include #include #include @@ -13,6 +14,29 @@ namespace sprout { struct container_traits; namespace detail { + // + // has_value_type + // has_iterator + // has_const_iterator + // has_reference + // has_const_reference + // has_size_type + // has_difference_type + // has_pointer + // has_const_pointer + // has_static_size + // + SPROUT_HAS_XXX_TYPE_DEF_LAZY(value_type); + SPROUT_HAS_XXX_TYPE_DEF_LAZY(iterator); + SPROUT_HAS_XXX_TYPE_DEF_LAZY(const_iterator); + SPROUT_HAS_XXX_TYPE_DEF_LAZY(reference); + SPROUT_HAS_XXX_TYPE_DEF_LAZY(const_reference); + SPROUT_HAS_XXX_TYPE_DEF_LAZY(size_type); + SPROUT_HAS_XXX_TYPE_DEF_LAZY(difference_type); + SPROUT_HAS_XXX_TYPE_DEF_LAZY(pointer); + SPROUT_HAS_XXX_TYPE_DEF_LAZY(const_pointer); + SPROUT_HAS_XXX_VALUE_DEF_LAZY(static_size); + // // inherit_if_value_type // inherit_if_iterator @@ -36,52 +60,332 @@ namespace sprout { SPROUT_INHERIT_IF_XXX_TYPE_DEF_LAZY(const_pointer); SPROUT_INHERIT_IF_XXX_CONSTANT_DEF_LAZY(static_size); - // - // has_static_size - // - SPROUT_HAS_XXX_VALUE_DEF_LAZY(static_size); - // // inherit_iterator_if_const_iterator + // inherit_const_iterator_if_iterator // inherit_reference_if_const_reference + // inherit_const_reference_if_reference // inherit_pointer_if_const_pointer + // inherit_const_pointer_if_pointer // SPROUT_INHERIT_ALIAS_IF_XXX_TYPE_DEF_LAZY(iterator, const_iterator); + SPROUT_INHERIT_ALIAS_IF_XXX_TYPE_DEF_LAZY(const_iterator, iterator); SPROUT_INHERIT_ALIAS_IF_XXX_TYPE_DEF_LAZY(reference, const_reference); + SPROUT_INHERIT_ALIAS_IF_XXX_TYPE_DEF_LAZY(const_reference, reference); SPROUT_INHERIT_ALIAS_IF_XXX_TYPE_DEF_LAZY(pointer, const_pointer); + SPROUT_INHERIT_ALIAS_IF_XXX_TYPE_DEF_LAZY(const_pointer, pointer); // - // inherit_if_fixed_size + // has_container_nosy_iterator // - template - struct inherit_if_fixed_size {}; template - struct inherit_if_fixed_size< - Container, - typename std::enable_if::value>::type - > { + struct has_container_nosy_iterator + : public std::integral_constant< + bool, + sprout::detail::has_iterator::value + || sprout::detail::has_const_iterator::value + > + {}; + // + // has_container_nosy_value_type + // + template + struct has_container_nosy_value_type + : public std::integral_constant< + bool, + sprout::detail::has_value_type::value + || sprout::detail::has_container_nosy_iterator::value + > + {}; + + // + // container_nosy_iterator + // + template + struct container_nosy_iterator_impl {}; + template + struct container_nosy_iterator_impl + : public sprout::detail::inherit_if_iterator + {}; + template + struct container_nosy_iterator_impl + : public sprout::detail::inherit_iterator_if_const_iterator + {}; + template + struct container_nosy_iterator + : public sprout::detail::container_nosy_iterator_impl< + Container, + sprout::detail::has_iterator::value, + sprout::detail::has_const_iterator::value + > + {}; + // + // container_nosy_const_iterator + // + template + struct container_nosy_const_iterator_impl {}; + template + struct container_nosy_const_iterator_impl + : public sprout::detail::inherit_if_const_iterator + {}; + template + struct container_nosy_const_iterator_impl + : public sprout::detail::inherit_const_iterator_if_iterator + {}; + template + struct container_nosy_const_iterator + : public sprout::detail::container_nosy_const_iterator_impl< + Container, + sprout::detail::has_const_iterator::value, + sprout::detail::has_iterator::value + > + {}; + // + // container_nosy_value_type + // + template + struct container_nosy_value_type_impl {}; + template + struct container_nosy_value_type_impl { + public: + typedef typename Container::value_type value_type; + }; + template + struct container_nosy_value_type_impl { + public: + typedef typename std::iterator_traits< + typename sprout::detail::container_nosy_iterator::iterator + >::value_type value_type; + }; + template + struct container_nosy_value_type + : public sprout::detail::container_nosy_value_type_impl< + Container, + sprout::detail::has_value_type::value, + sprout::detail::has_container_nosy_iterator::value + > + {}; + // + // container_nosy_reference + // + template + struct container_nosy_reference_impl {}; + template + struct container_nosy_reference_impl { + public: + typedef typename Container::reference reference; + }; + template + struct container_nosy_reference_impl { + public: + typedef typename Container::const_reference reference; + }; + template + struct container_nosy_reference_impl { + public: + typedef typename std::iterator_traits< + typename sprout::detail::container_nosy_iterator::iterator + >::reference reference; + }; + template + struct container_nosy_reference + : public sprout::detail::container_nosy_reference_impl< + Container, + sprout::detail::has_reference::value, + sprout::detail::has_const_reference::value, + sprout::detail::has_container_nosy_iterator::value + > + {}; + // + // container_nosy_const_reference + // + template + struct container_nosy_const_reference_impl {}; + template + struct container_nosy_const_reference_impl { + public: + typedef typename Container::const_reference const_reference; + }; + template + struct container_nosy_const_reference_impl { + public: + typedef typename Container::reference const_reference; + }; + template + struct container_nosy_const_reference_impl { + public: + typedef typename std::iterator_traits< + typename sprout::detail::container_nosy_const_iterator::const_iterator + >::reference const_reference; + }; + template + struct container_nosy_const_reference + : public sprout::detail::container_nosy_const_reference_impl< + Container, + sprout::detail::has_const_reference::value, + sprout::detail::has_reference::value, + sprout::detail::has_container_nosy_iterator::value + > + {}; + // + // container_nosy_difference_type + // + template + struct container_nosy_difference_type_impl { + public: + typedef std::ptrdiff_t difference_type; + }; + template + struct container_nosy_difference_type_impl { + public: + typedef typename Container::difference_type difference_type; + }; + template + struct container_nosy_difference_type_impl { + public: + typedef typename std::iterator_traits< + typename sprout::detail::container_nosy_iterator::iterator + >::difference_type difference_type; + }; + template + struct container_nosy_difference_type + : public sprout::detail::container_nosy_difference_type_impl< + Container, + sprout::detail::has_difference_type::value, + sprout::detail::has_container_nosy_iterator::value + > + {}; + // + // container_nosy_size_type + // + template + struct container_nosy_size_type_impl { + public: + typedef std::size_t size_type; + }; + template + struct container_nosy_size_type_impl { + public: + typedef typename Container::size_type size_type; + }; + template + struct container_nosy_size_type_impl { + public: + typedef typename std::make_unsigned< + typename std::iterator_traits< + typename sprout::detail::container_nosy_iterator::iterator + >::difference_type + >::type size_type; + }; + template + struct container_nosy_size_type + : public sprout::detail::container_nosy_size_type_impl< + Container, + sprout::detail::has_size_type::value, + sprout::detail::has_container_nosy_iterator::value + > + {}; + // + // container_nosy_pointer + // + template + struct container_nosy_pointer_impl {}; + template + struct container_nosy_pointer_impl { + public: + typedef typename Container::pointer pointer; + }; + template + struct container_nosy_pointer_impl { + public: + typedef typename Container::const_pointer pointer; + }; + template + struct container_nosy_pointer_impl { + public: + typedef typename sprout::detail::container_nosy_value_type::value_type* pointer; + }; + template + struct container_nosy_pointer + : public sprout::detail::container_nosy_pointer_impl< + Container, + sprout::detail::has_pointer::value, + sprout::detail::has_const_pointer::value, + sprout::detail::has_container_nosy_value_type::value + > + {}; + // + // container_nosy_const_pointer + // + template + struct container_nosy_const_pointer_impl {}; + template + struct container_nosy_const_pointer_impl { + public: + typedef typename Container::const_pointer const_pointer; + }; + template + struct container_nosy_const_pointer_impl { + public: + typedef typename Container::pointer const_pointer; + }; + template + struct container_nosy_const_pointer_impl { + public: + typedef typename sprout::detail::container_nosy_value_type::value_type const* const_pointer; + }; + template + struct container_nosy_const_pointer + : public sprout::detail::container_nosy_const_pointer_impl< + Container, + sprout::detail::has_const_pointer::value, + sprout::detail::has_pointer::value, + sprout::detail::has_container_nosy_value_type::value + > + {}; + // + // container_nosy_static_size + // + template + struct container_nosy_static_size + : public sprout::detail::inherit_if_static_size + {}; + // + // container_nosy_fixed_size + // + template + struct container_nosy_fixed_size_impl {}; + template + struct container_nosy_fixed_size_impl { public: static SPROUT_CONSTEXPR decltype(Container::static_size) fixed_size() { return Container::static_size; } }; + template + struct container_nosy_fixed_size + : public sprout::detail::container_nosy_fixed_size_impl< + Container, + sprout::detail::has_static_size::value + > + {}; // // container_traits_default // template struct container_traits_default - : public sprout::detail::inherit_if_value_type - , public sprout::detail::inherit_if_iterator - , public sprout::detail::inherit_if_const_iterator - , public sprout::detail::inherit_if_reference - , public sprout::detail::inherit_if_const_reference - , public sprout::detail::inherit_if_size_type - , public sprout::detail::inherit_if_difference_type - , public sprout::detail::inherit_if_pointer - , public sprout::detail::inherit_if_const_pointer - , public sprout::detail::inherit_if_static_size - , public sprout::detail::inherit_if_fixed_size + : public sprout::detail::container_nosy_value_type + , public sprout::detail::container_nosy_iterator + , public sprout::detail::container_nosy_const_iterator + , public sprout::detail::container_nosy_reference + , public sprout::detail::container_nosy_const_reference + , public sprout::detail::container_nosy_size_type + , public sprout::detail::container_nosy_difference_type + , public sprout::detail::container_nosy_pointer + , public sprout::detail::container_nosy_const_pointer + , public sprout::detail::container_nosy_static_size + , public sprout::detail::container_nosy_fixed_size {}; template struct container_traits_default { @@ -115,7 +419,7 @@ namespace sprout { , public sprout::detail::inherit_if_difference_type > , public sprout::detail::inherit_if_const_pointer > , public sprout::detail::inherit_if_static_size > - , public sprout::detail::inherit_if_fixed_size > + , public sprout::detail::container_nosy_fixed_size > , public sprout::detail::inherit_iterator_if_const_iterator > , public sprout::detail::inherit_reference_if_const_reference > , public sprout::detail::inherit_pointer_if_const_pointer > @@ -142,6 +446,24 @@ namespace sprout { struct container_traits : public sprout::detail::container_traits_const_default {}; + + // + // container_traits_facade + // + template + struct container_traits_facade + : public sprout::detail::inherit_if_value_type > + , public sprout::detail::inherit_if_iterator > + , public sprout::detail::inherit_if_const_iterator > + , public sprout::detail::inherit_if_reference > + , public sprout::detail::inherit_if_const_reference > + , public sprout::detail::inherit_if_size_type > + , public sprout::detail::inherit_if_difference_type > + , public sprout::detail::inherit_if_pointer > + , public sprout::detail::inherit_if_const_pointer > + , public sprout::detail::inherit_if_static_size > + , public sprout::detail::container_nosy_fixed_size > + {}; } // namespace sprout #endif // #ifndef SPROUT_CONTAINER_CONTAINER_TRAITS_HPP diff --git a/sprout/range/adaptor/copied.hpp b/sprout/range/adaptor/copied.hpp index f79b96e6..c0a6cb2d 100644 --- a/sprout/range/adaptor/copied.hpp +++ b/sprout/range/adaptor/copied.hpp @@ -25,7 +25,7 @@ namespace sprout { : public sprout::range::range_container< typename sprout::container_traits::iterator > - , public sprout::detail::inherit_if_fixed_size + , public sprout::detail::container_nosy_fixed_size { public: typedef Range range_type; diff --git a/sprout/range/adaptor/sinusoidal.hpp b/sprout/range/adaptor/sinusoidal.hpp index 14508ede..733d36cf 100644 --- a/sprout/range/adaptor/sinusoidal.hpp +++ b/sprout/range/adaptor/sinusoidal.hpp @@ -23,7 +23,7 @@ namespace sprout { : public sprout::range::range_container< sprout::sinusoid_iterator > - , public sprout::detail::inherit_if_fixed_size + , public sprout::detail::container_nosy_fixed_size { public: typedef Range range_type; diff --git a/sprout/range/adaptor/transformed.hpp b/sprout/range/adaptor/transformed.hpp index bbafc7df..4645f0cb 100644 --- a/sprout/range/adaptor/transformed.hpp +++ b/sprout/range/adaptor/transformed.hpp @@ -28,7 +28,7 @@ namespace sprout { typename sprout::container_traits::iterator > > - , public sprout::detail::inherit_if_fixed_size + , public sprout::detail::container_nosy_fixed_size { public: typedef BinaryFunction functor_type; @@ -62,7 +62,7 @@ namespace sprout { typename sprout::container_traits::iterator > > - , public sprout::detail::inherit_if_fixed_size + , public sprout::detail::container_nosy_fixed_size { public: typedef UnaryFunction functor_type; diff --git a/sprout/sub_array.hpp b/sprout/sub_array.hpp index 0c44d2eb..78bd6b22 100644 --- a/sprout/sub_array.hpp +++ b/sprout/sub_array.hpp @@ -28,29 +28,8 @@ namespace sprout { SPROUT_STATIC_CONSTEXPR bool is_reference = std::is_reference::value; SPROUT_STATIC_CONSTEXPR bool is_const = std::is_const::value; protected: - typedef typename sprout::container_traits::value_type value_type; - typedef typename std::conditional< - is_const, - typename sprout::container_traits::const_iterator, - typename sprout::container_traits::iterator - >::type iterator; - typedef typename sprout::container_traits::const_iterator const_iterator; - typedef typename std::conditional< - is_const, - typename sprout::container_traits::const_reference, - typename sprout::container_traits::reference - >::type reference; - typedef typename sprout::container_traits::const_reference const_reference; - typedef typename sprout::container_traits::size_type size_type; - typedef typename sprout::container_traits::difference_type difference_type; - typedef typename std::conditional< - is_const, - typename sprout::container_traits::const_pointer, - typename sprout::container_traits::pointer - >::type pointer; - typedef typename sprout::container_traits::const_pointer const_pointer; - protected: - SPROUT_STATIC_CONSTEXPR size_type static_size = sprout::container_traits::static_size; + typedef typename sprout::container_traits::const_iterator impl_const_iterator; + typedef typename sprout::container_traits::difference_type impl_difference_type; protected: typedef typename std::conditional< is_reference, @@ -121,8 +100,8 @@ namespace sprout { } protected: holder_type array_; - difference_type first_; - difference_type last_; + impl_difference_type first_; + impl_difference_type last_; public: sub_array_impl() = default; protected: @@ -131,8 +110,8 @@ namespace sprout { ContainerTag, param_type arr, sprout::index_tuple, - const_iterator first, - const_iterator last, + impl_const_iterator first, + impl_const_iterator last, typename std::enable_if::value>::type* = 0 ) : array_{to_holder(arr)[Indexes]...} @@ -144,8 +123,8 @@ namespace sprout { ContainerTag, param_type arr, sprout::index_tuple, - const_iterator first, - const_iterator last, + impl_const_iterator first, + impl_const_iterator last, typename std::enable_if::value>::type* = 0 ) : array_(to_holder(arr)) @@ -157,8 +136,8 @@ namespace sprout { ContainerTag, param_type arr, sprout::index_tuple, - difference_type first, - difference_type last, + impl_difference_type first, + impl_difference_type last, typename std::enable_if::value>::type* = 0 ) : array_{to_holder(arr)[Indexes]...} @@ -170,8 +149,8 @@ namespace sprout { ContainerTag, param_type arr, sprout::index_tuple, - difference_type first, - difference_type last, + impl_difference_type first, + impl_difference_type last, typename std::enable_if::value>::type* = 0 ) : array_(to_holder(arr)) @@ -187,9 +166,11 @@ namespace sprout { template class sub_array : private sprout::detail::sub_array_impl + , public sprout::container_traits_facade::type> { private: typedef sprout::detail::sub_array_impl impl_type; + typedef sprout::container_traits_facade::type> facade_type; public: typedef typename impl_type::container_type container_type; typedef typename impl_type::internal_type internal_type; @@ -197,17 +178,16 @@ namespace sprout { SPROUT_STATIC_CONSTEXPR bool is_reference = impl_type::is_reference; SPROUT_STATIC_CONSTEXPR bool is_const = impl_type::is_const; public: - typedef typename impl_type::value_type value_type; - typedef typename impl_type::iterator iterator; - typedef typename impl_type::const_iterator const_iterator; - typedef typename impl_type::reference reference; - typedef typename impl_type::const_reference const_reference; - typedef typename impl_type::size_type size_type; - typedef typename impl_type::difference_type difference_type; - typedef typename impl_type::pointer pointer; - typedef typename impl_type::const_pointer const_pointer; + typedef typename facade_type::iterator iterator; + typedef typename facade_type::const_iterator const_iterator; + typedef typename facade_type::reference reference; + typedef typename facade_type::const_reference const_reference; + typedef typename facade_type::size_type size_type; + typedef typename facade_type::difference_type difference_type; + typedef typename facade_type::pointer pointer; + typedef typename facade_type::const_pointer const_pointer; public: - SPROUT_STATIC_CONSTEXPR size_type static_size = impl_type::static_size; + SPROUT_STATIC_CONSTEXPR size_type static_size = facade_type::static_size; public: typedef typename impl_type::holder_type holder_type; typedef typename impl_type::param_type param_type; @@ -378,6 +358,14 @@ namespace sprout { template SPROUT_CONSTEXPR typename sprout::sub_array::size_type sprout::sub_array::static_size; + // + // swap + // + template + inline void swap(sprout::sub_array& lhs, sprout::sub_array& rhs) { + lhs.swap(rhs); + } + // // operator== // operator!= @@ -387,38 +375,39 @@ namespace sprout { // operator>= // template - inline SPROUT_CONSTEXPR bool operator==(sprout::sub_array const& lhs, sprout::sub_array const& rhs) { + inline SPROUT_CONSTEXPR bool + operator==(sprout::sub_array const& lhs, sprout::sub_array const& rhs) { return NS_SSCRISK_CEL_OR_SPROUT::equal(sprout::begin(lhs), sprout::end(lhs), sprout::begin(rhs)); } template - inline SPROUT_CONSTEXPR bool operator!=(sprout::sub_array const& lhs, sprout::sub_array const& rhs) { + inline SPROUT_CONSTEXPR bool + operator!=(sprout::sub_array const& lhs, sprout::sub_array const& rhs) { return !(lhs == rhs); } template - inline SPROUT_CONSTEXPR bool operator<(sprout::sub_array const& lhs, sprout::sub_array const& rhs) { - return NS_SSCRISK_CEL_OR_SPROUT::lexicographical_compare(sprout::begin(lhs), sprout::end(lhs), sprout::begin(rhs), sprout::end(rhs)); + inline SPROUT_CONSTEXPR bool + operator<(sprout::sub_array const& lhs, sprout::sub_array const& rhs) { + return NS_SSCRISK_CEL_OR_SPROUT::lexicographical_compare( + sprout::begin(lhs), sprout::end(lhs), + sprout::begin(rhs), sprout::end(rhs) + ); } template - inline SPROUT_CONSTEXPR bool operator>(sprout::sub_array const& lhs, sprout::sub_array const& rhs) { + inline SPROUT_CONSTEXPR bool + operator>(sprout::sub_array const& lhs, sprout::sub_array const& rhs) { return rhs < lhs; } template - inline SPROUT_CONSTEXPR bool operator<=(sprout::sub_array const& lhs, sprout::sub_array const& rhs) { + inline SPROUT_CONSTEXPR bool + operator<=(sprout::sub_array const& lhs, sprout::sub_array const& rhs) { return !(rhs < lhs); } template - inline SPROUT_CONSTEXPR bool operator>=(sprout::sub_array const& lhs, sprout::sub_array const& rhs) { + inline SPROUT_CONSTEXPR bool + operator>=(sprout::sub_array const& lhs, sprout::sub_array const& rhs) { return !(lhs < rhs); } - // - // swap - // - template - inline void swap(sprout::sub_array& lhs, sprout::sub_array& rhs) { - lhs.swap(rhs); - } - // // container_construct_traits // diff --git a/sprout/type_traits/has_xxx.hpp b/sprout/type_traits/has_xxx.hpp index a944d18e..b083b116 100644 --- a/sprout/type_traits/has_xxx.hpp +++ b/sprout/type_traits/has_xxx.hpp @@ -41,6 +41,6 @@ // SPROUT_HAS_XXX_VALUE_DEF_LAZY // #define SPROUT_HAS_XXX_VALUE_DEF_LAZY(VALUE) \ - SPROUT_HAS_XXX_TYPE_DEF(SPROUT_PP_CAT(has_, VALUE), VALUE) + SPROUT_HAS_XXX_VALUE_DEF(SPROUT_PP_CAT(has_, VALUE), VALUE) #endif // #ifndef SPROUT_TYPE_TRAITS_HAS_XXX_HPP diff --git a/sprout/type_traits/inherit_if_xxx.hpp b/sprout/type_traits/inherit_if_xxx.hpp index f5eabcb6..d67078fb 100644 --- a/sprout/type_traits/inherit_if_xxx.hpp +++ b/sprout/type_traits/inherit_if_xxx.hpp @@ -49,7 +49,12 @@ > { \ public: \ SPROUT_STATIC_CONSTEXPR decltype(T::CONSTANT) ALIAS = T::CONSTANT; \ - } + }; \ + template \ + SPROUT_CONSTEXPR decltype(T::CONSTANT) NAME< \ + T, \ + typename std::enable_if::value>::type \ + >::ALIAS #define SPROUT_INHERIT_ALIAS_IF_XXX_CONSTANT_DEF_LAZY(ALIAS, CONSTANT) \ SPROUT_INHERIT_ALIAS_IF_XXX_CONSTANT_DEF(SPROUT_PP_CAT(SPROUT_PP_CAT(SPROUT_PP_CAT(inherit_, ALIAS), _if_), CONSTANT), ALIAS, CONSTANT)