diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2017-09-13 11:24:46 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2017-09-13 11:25:39 +0900 |
commit | 4fadd968fa12130524c8380f33fcfe25d4de79e5 (patch) | |
tree | fd26a490cd15388d42fc6652b3c5c13012e7f93e /boost/test/utils/is_forward_iterable.hpp | |
parent | b5c87084afaef42b2d058f68091be31988a6a874 (diff) | |
download | boost-4fadd968fa12130524c8380f33fcfe25d4de79e5.tar.gz boost-4fadd968fa12130524c8380f33fcfe25d4de79e5.tar.bz2 boost-4fadd968fa12130524c8380f33fcfe25d4de79e5.zip |
Imported Upstream version 1.65.0upstream/1.65.0
Change-Id: Icf8400b375482cb11bcf77440a6934ba360d6ba4
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
Diffstat (limited to 'boost/test/utils/is_forward_iterable.hpp')
-rw-r--r-- | boost/test/utils/is_forward_iterable.hpp | 88 |
1 files changed, 78 insertions, 10 deletions
diff --git a/boost/test/utils/is_forward_iterable.hpp b/boost/test/utils/is_forward_iterable.hpp index b218e96cba..e8f5d39467 100644 --- a/boost/test/utils/is_forward_iterable.hpp +++ b/boost/test/utils/is_forward_iterable.hpp @@ -36,6 +36,7 @@ // Boost #include <boost/utility/declval.hpp> +#include <boost/range.hpp> #include <boost/type_traits/is_same.hpp> #include <boost/type_traits/remove_reference.hpp> #include <boost/type_traits/remove_cv.hpp> @@ -51,6 +52,9 @@ namespace boost { namespace unit_test { +template<typename T> +struct is_forward_iterable; + // ************************************************************************** // // ************** is_forward_iterable ************** // // ************************************************************************** // @@ -65,6 +69,9 @@ struct is_forward_iterable<T const> : public is_forward_iterable<T> {}; template<typename T> struct is_forward_iterable<T&> : public is_forward_iterable<T> {}; +template<typename T, std::size_t N> +struct is_forward_iterable< T [N] > : public mpl::true_ {}; + template<typename T, typename A> struct is_forward_iterable< std::vector<T, A> > : public mpl::true_ {}; @@ -86,6 +93,7 @@ struct is_forward_iterable< std::string > : public mpl::true_ {}; namespace ut_detail { +// SFINAE helper template<typename T> struct is_present : public mpl::true_ {}; @@ -110,10 +118,12 @@ template <class T> struct has_member_begin { private: struct nil_t {}; - template<typename U> static auto test( U* ) -> decltype(boost::declval<U>().begin()); + template<typename U> static auto test( U* ) -> decltype(std::begin(boost::declval<U&>())); // does not work with boost::begin template<typename> static nil_t test( ... ); public: static bool const value = !std::is_same< decltype(test<T>( nullptr )), nil_t>::value; + + }; //____________________________________________________________________________// @@ -122,7 +132,7 @@ template <class T> struct has_member_end { private: struct nil_t {}; - template<typename U> static auto test( U* ) -> decltype(boost::declval<U>().end()); + template<typename U> static auto test( U* ) -> decltype(std::end(boost::declval<U&>())); // does not work with boost::end template<typename> static nil_t test( ... ); public: static bool const value = !std::is_same< decltype(test<T>( nullptr )), nil_t>::value; @@ -134,24 +144,36 @@ template <class T, class enabled = void> struct is_forward_iterable_impl : std::false_type { }; -//____________________________________________________________________________// - template <class T> struct is_forward_iterable_impl< T, typename std::enable_if< - is_present<typename T::const_iterator>::value && - is_present<typename T::value_type>::value && - has_member_size<T>::value && - has_member_begin<T>::value && - has_member_end<T>::value && - !is_cstring<T>::value + has_member_begin<T>::value && + has_member_end<T>::value >::type > : std::true_type {}; //____________________________________________________________________________// +template <class T, class enabled = void> +struct is_container_forward_iterable_impl : std::false_type { +}; + +template <class T> +struct is_container_forward_iterable_impl< + T, + typename std::enable_if< + is_present<typename T::const_iterator>::value && + is_present<typename T::value_type>::value && + has_member_size<T>::value && + is_forward_iterable_impl<T>::value + >::type +> : is_forward_iterable_impl<T> +{}; + +//____________________________________________________________________________// + } // namespace ut_detail /*! Indicates that a specific type implements the forward iterable concept. */ @@ -163,8 +185,54 @@ struct is_forward_iterable { enum { value = is_fwd_it_t::value }; }; +/*! Indicates that a specific type implements the forward iterable concept. */ +template<typename T> +struct is_container_forward_iterable { + typedef typename std::remove_reference<T>::type T_ref; + typedef ut_detail::is_container_forward_iterable_impl<T_ref> is_fwd_it_t; + typedef mpl::bool_<is_fwd_it_t::value> type; + enum { value = is_fwd_it_t::value }; +}; + #endif /* defined(BOOST_TEST_FWD_ITERABLE_CXX03) */ +template <typename T, bool is_forward_iterable = is_forward_iterable<T>::value > +struct bt_iterator_traits; + +template <typename T> +struct bt_iterator_traits< T, true >{ + BOOST_STATIC_ASSERT((is_forward_iterable<T>::value)); //, "only for forward iterable types"); + typedef typename T::const_iterator const_iterator; + typedef typename T::value_type value_type; + + static const_iterator begin(T const& container) { + return container.begin(); + } + static const_iterator end(T const& container) { + return container.end(); + } + static std::size_t size(T const& container) { + return container.size(); + } +}; + +template <typename T, std::size_t N> +struct bt_iterator_traits< T [N], true > { + typedef typename boost::add_const<T>::type T_const; + typedef typename boost::add_pointer<T_const>::type const_iterator; + typedef T value_type; + + static const_iterator begin(T_const (&array)[N]) { + return &array[0]; + } + static const_iterator end(T_const (&array)[N]) { + return &array[N]; + } + static std::size_t size(T_const (&)[N]) { + return N; + } +}; + } // namespace unit_test } // namespace boost |