summaryrefslogtreecommitdiff
path: root/boost/range/size_type.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/range/size_type.hpp')
-rw-r--r--boost/range/size_type.hpp56
1 files changed, 33 insertions, 23 deletions
diff --git a/boost/range/size_type.hpp b/boost/range/size_type.hpp
index 8c184f87d2..c6fb54bb15 100644
--- a/boost/range/size_type.hpp
+++ b/boost/range/size_type.hpp
@@ -16,11 +16,13 @@
#endif
#include <boost/range/config.hpp>
-
+#include <boost/range/difference_type.hpp>
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#include <boost/range/detail/size_type.hpp>
#else
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/make_unsigned.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <cstddef>
#include <utility>
@@ -33,36 +35,44 @@ namespace boost
//////////////////////////////////////////////////////////////////////////
// default
//////////////////////////////////////////////////////////////////////////
-
- template< typename C >
- struct range_size
+
+ template<typename T>
+ class has_size_type
{
- typedef BOOST_DEDUCED_TYPENAME C::size_type type;
+ typedef char no_type;
+ struct yes_type { char dummy[2]; };
+
+ template<typename C>
+ static yes_type test(BOOST_DEDUCED_TYPENAME C::size_type x);
+
+ template<typename C, typename Arg>
+ static no_type test(Arg x);
+
+ public:
+ static const bool value = sizeof(test<T>(0)) == sizeof(yes_type);
};
-
- //////////////////////////////////////////////////////////////////////////
- // pair
- //////////////////////////////////////////////////////////////////////////
-
- template< typename Iterator >
- struct range_size< std::pair<Iterator,Iterator> >
+
+ template<typename C, typename Enabler=void>
+ struct range_size
{
- typedef std::size_t type;
+ typedef BOOST_DEDUCED_TYPENAME make_unsigned<
+ BOOST_DEDUCED_TYPENAME range_difference<C>::type
+ >::type type;
};
-
- //////////////////////////////////////////////////////////////////////////
- // array
- //////////////////////////////////////////////////////////////////////////
-
- template< typename T, std::size_t sz >
- struct range_size< T[sz] >
+
+ template<typename C>
+ struct range_size<
+ C,
+ BOOST_DEDUCED_TYPENAME enable_if<has_size_type<C>, void>::type
+ >
{
- typedef std::size_t type;
+ typedef BOOST_DEDUCED_TYPENAME C::size_type type;
};
+
}
template< class T >
- struct range_size :
+ struct range_size :
detail::range_size<T>
{ };
@@ -70,7 +80,7 @@ namespace boost
struct range_size<const T >
: detail::range_size<T>
{ };
-
+
} // namespace boost
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION