File indexing completed on 2025-01-18 09:52:42
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef BOOST_TEST_UTILS_IS_FORWARD_ITERABLE_HPP
0013 #define BOOST_TEST_UTILS_IS_FORWARD_ITERABLE_HPP
0014
0015 #if defined(BOOST_NO_CXX11_DECLTYPE) || \
0016 defined(BOOST_NO_CXX11_NULLPTR) || \
0017 defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES)
0018
0019
0020 #if !defined(BOOST_MSVC) || BOOST_MSVC_FULL_VER < 170061232
0021 #define BOOST_TEST_FWD_ITERABLE_CXX03
0022 #endif
0023 #endif
0024
0025 #if defined(BOOST_TEST_FWD_ITERABLE_CXX03)
0026
0027 #include <boost/mpl/bool.hpp>
0028
0029
0030 #include <list>
0031 #include <vector>
0032 #include <map>
0033 #include <set>
0034
0035 #else
0036
0037
0038 #include <boost/static_assert.hpp>
0039 #include <boost/utility/declval.hpp>
0040 #include <boost/type_traits/is_same.hpp>
0041 #include <boost/type_traits/remove_reference.hpp>
0042 #include <boost/type_traits/remove_cv.hpp>
0043 #include <boost/test/utils/is_cstring.hpp>
0044
0045
0046 #include <utility>
0047 #include <type_traits>
0048
0049 #endif
0050
0051
0052 namespace boost {
0053 namespace unit_test {
0054
0055 template<typename T>
0056 struct is_forward_iterable;
0057
0058
0059
0060
0061
0062 #if defined(BOOST_TEST_FWD_ITERABLE_CXX03) && !defined(BOOST_TEST_DOXYGEN_DOC__)
0063 template<typename T>
0064 struct is_forward_iterable : public mpl::false_ {};
0065
0066 template<typename T>
0067 struct is_forward_iterable<T const> : public is_forward_iterable<T> {};
0068
0069 template<typename T>
0070 struct is_forward_iterable<T&> : public is_forward_iterable<T> {};
0071
0072 template<typename T, std::size_t N>
0073 struct is_forward_iterable< T [N] > : public mpl::true_ {};
0074
0075 template<typename T, typename A>
0076 struct is_forward_iterable< std::vector<T, A> > : public mpl::true_ {};
0077
0078 template<typename T, typename A>
0079 struct is_forward_iterable< std::list<T, A> > : public mpl::true_ {};
0080
0081 template<typename K, typename V, typename C, typename A>
0082 struct is_forward_iterable< std::map<K, V, C, A> > : public mpl::true_ {};
0083
0084 template<typename K, typename C, typename A>
0085 struct is_forward_iterable< std::set<K, C, A> > : public mpl::true_ {};
0086
0087
0088
0089 template<>
0090 struct is_forward_iterable< std::string > : public mpl::true_ {};
0091
0092 #else
0093
0094 namespace ut_detail {
0095
0096
0097 template<typename T>
0098 struct is_present : public mpl::true_ {};
0099
0100
0101
0102
0103
0104 template <class T>
0105 struct has_member_size {
0106 private:
0107 struct nil_t {};
0108 template<typename U> static auto test( U* ) -> decltype(boost::declval<U>().size());
0109 template<typename> static nil_t test( ... );
0110
0111 public:
0112 static bool const value = !std::is_same< decltype(test<T>( nullptr )), nil_t>::value;
0113 };
0114
0115
0116
0117 template <class T>
0118 struct has_member_begin {
0119 private:
0120 struct nil_t {};
0121 template<typename U> static auto test( U* ) -> decltype(std::begin(boost::declval<U&>()));
0122 template<typename> static nil_t test( ... );
0123 public:
0124 static bool const value = !std::is_same< decltype(test<T>( nullptr )), nil_t>::value;
0125 };
0126
0127
0128
0129 template <class T>
0130 struct has_member_end {
0131 private:
0132 struct nil_t {};
0133 template<typename U> static auto test( U* ) -> decltype(std::end(boost::declval<U&>()));
0134 template<typename> static nil_t test( ... );
0135 public:
0136 static bool const value = !std::is_same< decltype(test<T>( nullptr )), nil_t>::value;
0137 };
0138
0139
0140
0141 template <class T, class enabled = void>
0142 struct is_forward_iterable_impl : std::false_type {
0143 };
0144
0145 template <class T>
0146 struct is_forward_iterable_impl<
0147 T,
0148 typename std::enable_if<
0149 has_member_begin<T>::value &&
0150 has_member_end<T>::value
0151 >::type
0152 > : std::true_type
0153 {};
0154
0155
0156
0157 template <class T, class enabled = void>
0158 struct is_container_forward_iterable_impl : std::false_type {
0159 };
0160
0161 template <class T>
0162 struct is_container_forward_iterable_impl<
0163 T,
0164 typename std::enable_if<
0165 is_present<typename T::const_iterator>::value &&
0166 is_present<typename T::value_type>::value &&
0167 has_member_size<T>::value &&
0168 is_forward_iterable_impl<T>::value
0169 >::type
0170 > : is_forward_iterable_impl<T>
0171 {};
0172
0173
0174
0175 }
0176
0177
0178 template<typename T>
0179 struct is_forward_iterable {
0180 typedef typename std::remove_reference<T>::type T_ref;
0181 typedef ut_detail::is_forward_iterable_impl<T_ref> is_fwd_it_t;
0182 typedef mpl::bool_<is_fwd_it_t::value> type;
0183 enum { value = is_fwd_it_t::value };
0184 };
0185
0186
0187 template<typename T>
0188 struct is_container_forward_iterable {
0189 typedef typename std::remove_reference<T>::type T_ref;
0190 typedef ut_detail::is_container_forward_iterable_impl<T_ref> is_fwd_it_t;
0191 typedef mpl::bool_<is_fwd_it_t::value> type;
0192 enum { value = is_fwd_it_t::value };
0193 };
0194
0195 #endif
0196
0197
0198
0199 template <typename T, bool is_forward_iterable = is_forward_iterable<T>::value >
0200 struct bt_iterator_traits;
0201
0202 template <typename T>
0203 struct bt_iterator_traits< T, true >{
0204 BOOST_STATIC_ASSERT((is_forward_iterable<T>::value));
0205
0206 #if defined(BOOST_TEST_FWD_ITERABLE_CXX03) || \
0207 (defined(BOOST_MSVC) && (BOOST_MSVC_FULL_VER <= 170061232))
0208 typedef typename T::const_iterator const_iterator;
0209 typedef typename std::iterator_traits<const_iterator>::value_type value_type;
0210 #else
0211 typedef decltype(boost::declval<
0212 typename boost::add_const<
0213 typename boost::remove_reference<T>::type
0214 >::type>().begin()) const_iterator;
0215
0216 typedef typename std::iterator_traits<const_iterator>::value_type value_type;
0217 #endif
0218
0219 static const_iterator begin(T const& container) {
0220 return container.begin();
0221 }
0222 static const_iterator end(T const& container) {
0223 return container.end();
0224 }
0225
0226 #if defined(BOOST_TEST_FWD_ITERABLE_CXX03) || \
0227 (defined(BOOST_MSVC) && (BOOST_MSVC_FULL_VER <= 170061232))
0228 static std::size_t
0229 size(T const& container) {
0230 return container.size();
0231 }
0232 #else
0233 static std::size_t
0234 size(T const& container) {
0235 return size(container,
0236 std::integral_constant<bool, ut_detail::has_member_size<T>::value>());
0237 }
0238 private:
0239 static std::size_t
0240 size(T const& container, std::true_type) { return container.size(); }
0241
0242 static std::size_t
0243 size(T const& container, std::false_type) { return std::distance(begin(container), end(container)); }
0244 #endif
0245 };
0246
0247 template <typename T, std::size_t N>
0248 struct bt_iterator_traits< T [N], true > {
0249 typedef typename boost::add_const<T>::type T_const;
0250 typedef typename boost::add_pointer<T_const>::type const_iterator;
0251 typedef T value_type;
0252
0253 static const_iterator begin(T_const (&array)[N]) {
0254 return &array[0];
0255 }
0256 static const_iterator end(T_const (&array)[N]) {
0257 return &array[N];
0258 }
0259 static std::size_t size(T_const (&)[N]) {
0260 return N;
0261 }
0262 };
0263
0264 }
0265 }
0266
0267 #endif