// Copyright (c) 2009-2020 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 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 BOOST_CONSTEXPR_OR_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::value>::type> { using type = typename boost::range_iterator::type; using const_type = typename boost::range_iterator::type; using value_type = typename boost::iterator_value::type; }; template struct iterator { using value_type = typename boost::remove_const::type; using type = T*; using const_type = value_type const*; }; template struct range_base { using value_type = typename cnv::iterator::value_type; using iterator = typename cnv::iterator::type; using const_iterator = typename cnv::iterator::const_type; using sentry_type = const_iterator; 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::value>::type> : public range_base { using this_type = range; using base_type = range_base; using iterator = typename base_type::iterator; using const_iterator = typename base_type::const_iterator; using sentry_type = const_iterator; 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::value>::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