// Copyright (c) 2009-2016 Vladimir Batov. // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. See http://www.boost.org/LICENSE_1_0.txt. #ifndef BOOST_CONVERT_DETAIL_RANGE_HPP #define BOOST_CONVERT_DETAIL_RANGE_HPP #include #include #include #include namespace boost { namespace cnv { namespace detail { template struct is_range : std::false_type {}; template struct is_range { BOOST_DECLARE_HAS_MEMBER(has_begin, begin); BOOST_DECLARE_HAS_MEMBER( has_end, end); static bool const value = has_begin::value && has_end::value; }; } template struct is_range : detail::is_range::type, boost::is_class::value> {}; template struct range; template struct iterator; template struct iterator >::type> { typedef typename boost::range_iterator::type type; typedef typename boost::range_iterator::type const_type; typedef typename boost::iterator_value::type value_type; }; template struct iterator { typedef typename boost::remove_const::type value_type; typedef T* type; typedef value_type const* const_type; }; template struct range_base { typedef typename cnv::iterator::value_type value_type; typedef typename cnv::iterator::type iterator; typedef typename cnv::iterator::const_type const_iterator; typedef const_iterator sentry_type; iterator begin () { return begin_; } const_iterator begin () const { return begin_; } void operator++ () { ++begin_; } // void operator-- () { --end_; } protected: range_base (iterator b, iterator e) : begin_(b), end_(e) {} iterator begin_; iterator mutable end_; }; template struct range >::type> : public range_base { typedef range this_type; typedef range_base base_type; typedef typename base_type::iterator iterator; typedef typename base_type::const_iterator const_iterator; typedef const_iterator sentry_type; range (T& r) : base_type(r.begin(), r.end()) {} iterator end () { return base_type::end_; } const_iterator end () const { return base_type::end_; } sentry_type sentry () const { return base_type::end_; } std::size_t size () const { return base_type::end_ - base_type::begin_; } bool empty () const { return base_type::begin_ == base_type::end_; } }; template struct range >::type> : public range_base { using this_type = range; using base_type = range_base; using value_type = typename boost::remove_const::type; using iterator = T*; using const_iterator = value_type const*; struct sentry_type { friend bool operator!=(iterator it, sentry_type) { return !!*it; } }; range (iterator b, iterator e =0) : base_type(b, e) {} iterator end () { return base_type::end_ ? base_type::end_ : (base_type::end_ = base_type::begin_ + size()); } const_iterator end () const { return base_type::end_ ? base_type::end_ : (base_type::end_ = base_type::begin_ + size()); } sentry_type sentry () const { return sentry_type(); } std::size_t size () const { return std::char_traits::length(base_type::begin_); } bool empty () const { return !*base_type::begin_; } }; template struct range : public range { range (T* b, T* e =0) : range(b, e) {} }; template struct range : public range { range (T* b, T* e =0) : range(b, e) {} }; }} #endif // BOOST_CONVERT_DETAIL_RANGE_HPP