1 // Boost.Range library 2 // 3 // Copyright Thorsten Ottosen 2003-2004. Use, modification and 4 // distribution is subject to the Boost Software License, Version 5 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at 6 // http://www.boost.org/LICENSE_1_0.txt) 7 // 8 // For more information, see http://www.boost.org/libs/range/ 9 // 10 11 #ifndef BOOST_RANGE_SIZE_TYPE_HPP 12 #define BOOST_RANGE_SIZE_TYPE_HPP 13 14 #if defined(_MSC_VER) 15 # pragma once 16 #endif 17 18 #include <boost/range/config.hpp> 19 #include <boost/range/difference_type.hpp> 20 #include <boost/range/concepts.hpp> 21 #include <boost/range/has_range_iterator.hpp> 22 23 #include <boost/utility/enable_if.hpp> 24 #include <boost/type_traits/make_unsigned.hpp> 25 #include <boost/type_traits/remove_const.hpp> 26 #include <cstddef> 27 #include <utility> 28 29 namespace boost 30 { 31 namespace detail 32 { 33 34 ////////////////////////////////////////////////////////////////////////// 35 // default 36 ////////////////////////////////////////////////////////////////////////// 37 38 template<typename T> 39 class has_size_type 40 { 41 typedef char no_type; 42 struct yes_type { char dummy[2]; }; 43 44 template<typename C> 45 static yes_type test(BOOST_DEDUCED_TYPENAME C::size_type x); 46 47 template<typename C> 48 static no_type test(...); 49 50 public: 51 static const bool value = sizeof(test<T>(0)) == sizeof(yes_type); 52 }; 53 54 template<typename C, typename Enabler=void> 55 struct range_size_ 56 { 57 typedef BOOST_DEDUCED_TYPENAME make_unsigned< 58 BOOST_DEDUCED_TYPENAME range_difference<C>::type 59 >::type type; 60 }; 61 62 template<typename C> 63 struct range_size_< 64 C, 65 BOOST_DEDUCED_TYPENAME ::boost::enable_if<has_size_type<C>, void>::type 66 > 67 { 68 typedef BOOST_DEDUCED_TYPENAME C::size_type type; 69 }; 70 71 template<typename C, bool B = range_detail::has_type< range_iterator<C> >::value> 72 struct range_size 73 { }; 74 75 template<typename C> 76 struct range_size<C, true> 77 : range_size_<C> 78 { }; 79 } 80 81 template< class T > 82 struct range_size : 83 detail::range_size<T> 84 { }; 85 86 } // namespace boost 87 88 89 90 #endif 91