From f662a07bcc303ad5f56b37a2141be60f50f38d98 Mon Sep 17 00:00:00 2001 From: Neil Groves Date: Sun, 15 Sep 2013 21:54:32 +0000 Subject: [PATCH] [boost][range] Ticket 8702 - size_type detection [SVN r85690] --- include/boost/range/size_type.hpp | 13 ++- test/extension_size.cpp | 143 ++++++++++++++++++++++++++++-- 2 files changed, 147 insertions(+), 9 deletions(-) diff --git a/include/boost/range/size_type.hpp b/include/boost/range/size_type.hpp index c6fb54b..dab2f0d 100644 --- a/include/boost/range/size_type.hpp +++ b/include/boost/range/size_type.hpp @@ -17,6 +17,7 @@ #include #include +#include #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION #include #else @@ -45,8 +46,8 @@ namespace boost template static yes_type test(BOOST_DEDUCED_TYPENAME C::size_type x); - template - static no_type test(Arg x); + template + static no_type test(...); public: static const bool value = sizeof(test(0)) == sizeof(yes_type); @@ -74,12 +75,16 @@ namespace boost template< class T > struct range_size : detail::range_size - { }; + { + BOOST_RANGE_CONCEPT_ASSERT((boost::SinglePassRangeConcept)); + }; template< class T > struct range_size : detail::range_size - { }; + { + BOOST_RANGE_CONCEPT_ASSERT((boost::SinglePassRangeConcept)); + }; } // namespace boost diff --git a/test/extension_size.cpp b/test/extension_size.cpp index 6c7157f..0df8f22 100644 --- a/test/extension_size.cpp +++ b/test/extension_size.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -27,6 +28,13 @@ namespace boost_range_extension_size_test class FooWithoutSize { typedef std::list impl_t; + + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::range_size >::type, + std::list::size_type + >::value)); + typedef impl_t::const_iterator const_iterator; typedef impl_t::iterator iterator; @@ -39,12 +47,117 @@ namespace boost_range_extension_size_test private: impl_t m_impl; }; - - inline boost::range_size >::type - range_calculate_size(const FooWithoutSize& rng) + + template + class FooWithSize { - return 2u; - } + public: + typedef SizeType size_type; + typedef boost::uint8_t* iterator; + typedef const boost::uint8_t* const_iterator; + + const_iterator begin() const; + iterator begin(); + const_iterator end() const; + iterator end(); + }; + + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::uint8_t, + boost::range_size >::type + >::value + )); + + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::uint16_t, + boost::range_size >::type + >::value + )); + + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::uint32_t, + boost::range_size >::type + >::value + )); + + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::uint64_t, + boost::range_size >::type + >::value + )); + + class UdtSizeType + { + public: + typedef boost::uint16_t value_type; + + UdtSizeType() : value_(0) { } + UdtSizeType(value_type value) : value_(value) { } + + operator value_type() const { return value_; } + + private: + value_type value_; + }; + + BOOST_STATIC_ASSERT(( + boost::is_same< + UdtSizeType, + boost::range_size >::type + >::value + )); + + class Foo2WithoutSize + { + public: + struct const_iterator + { + typedef std::forward_iterator_tag iterator_category; + typedef boost::int8_t difference_type; + typedef boost::int16_t value_type; + typedef value_type* pointer; + typedef value_type& reference; + + reference operator*() const; + pointer operator->() const; + const_iterator& operator++(); + const_iterator operator++(int); + bool operator==(const const_iterator&) const; + bool operator!=(const const_iterator&) const; + }; + + struct iterator : const_iterator + { + typedef const value_type* pointer; + typedef const value_type& reference; + + reference operator*() const; + pointer operator->() const; + + iterator& operator++(); + iterator operator++(int); + + bool operator==(const iterator&) const; + bool operator!=(const iterator&) const; + }; + + const_iterator begin() const; + iterator begin(); + const_iterator end() const; + iterator end(); + }; + + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::uint8_t, + boost::range_size< + ::boost_range_extension_size_test::Foo2WithoutSize>::type + >::value + )); } namespace boost @@ -60,6 +173,26 @@ namespace boost }; } +namespace boost_range_extension_size_test +{ + inline boost::range_size::type + range_calculate_size(const FooWithoutSize& rng) + { + return 2u; + } +} + +BOOST_STATIC_ASSERT(( + boost::is_same< + typename boost::make_unsigned::type, + typename boost::range_size< + boost_range_extension_size_test::FooWithoutSize>::type + >::value +)); + +typedef boost::make_unsigned::type t1; +typedef boost::range_size::type t1; + namespace {