File indexing completed on 2025-01-18 09:30:27
0001
0002
0003
0004
0005 #ifndef BOOST_CONVERT_DETAIL_RANGE_HPP
0006 #define BOOST_CONVERT_DETAIL_RANGE_HPP
0007
0008 #include <boost/convert/detail/has_member.hpp>
0009 #include <boost/convert/detail/char.hpp>
0010 #include <boost/range/iterator.hpp>
0011
0012 namespace boost { namespace cnv
0013 {
0014 namespace detail
0015 {
0016 template<typename T, bool is_class> struct is_range : std::false_type {};
0017
0018 template<typename T> struct is_range<T, true>
0019 {
0020 BOOST_DECLARE_HAS_MEMBER(has_begin, begin);
0021 BOOST_DECLARE_HAS_MEMBER( has_end, end);
0022
0023 static bool BOOST_CONSTEXPR_OR_CONST value = has_begin<T>::value && has_end<T>::value;
0024 };
0025 }
0026 template<typename T> struct is_range : detail::is_range<typename boost::remove_const<T>::type, boost::is_class<T>::value> {};
0027 template<typename T, typename enable =void> struct range;
0028 template<typename T, typename enable =void> struct iterator;
0029
0030 template<typename T>
0031 struct iterator<T, typename std::enable_if<is_range<T>::value>::type>
0032 {
0033 using type = typename boost::range_iterator<T>::type;
0034 using const_type = typename boost::range_iterator<T const>::type;
0035 using value_type = typename boost::iterator_value<type>::type;
0036 };
0037 template<typename T>
0038 struct iterator<T*, void>
0039 {
0040 using value_type = typename boost::remove_const<T>::type;
0041 using type = T*;
0042 using const_type = value_type const*;
0043 };
0044 template<typename T>
0045 struct range_base
0046 {
0047 using value_type = typename cnv::iterator<T>::value_type;
0048 using iterator = typename cnv::iterator<T>::type;
0049 using const_iterator = typename cnv::iterator<T>::const_type;
0050 using sentry_type = const_iterator;
0051
0052 iterator begin () { return begin_; }
0053 const_iterator begin () const { return begin_; }
0054 void operator++ () { ++begin_; }
0055
0056
0057 protected:
0058
0059 range_base (iterator b, iterator e) : begin_(b), end_(e) {}
0060
0061 iterator begin_;
0062 iterator mutable end_;
0063 };
0064
0065 template<typename T>
0066 struct range<T, typename std::enable_if<is_range<T>::value>::type> : public range_base<T>
0067 {
0068 using this_type = range;
0069 using base_type = range_base<T>;
0070 using iterator = typename base_type::iterator;
0071 using const_iterator = typename base_type::const_iterator;
0072 using sentry_type = const_iterator;
0073
0074 range (T& r) : base_type(r.begin(), r.end()) {}
0075
0076 iterator end () { return base_type::end_; }
0077 const_iterator end () const { return base_type::end_; }
0078 sentry_type sentry () const { return base_type::end_; }
0079 std::size_t size () const { return base_type::end_ - base_type::begin_; }
0080 bool empty () const { return base_type::begin_ == base_type::end_; }
0081 };
0082
0083 template<typename T>
0084 struct range<T*, typename std::enable_if<cnv::is_char<T>::value>::type> : public range_base<T*>
0085 {
0086 using this_type = range;
0087 using base_type = range_base<T*>;
0088 using value_type = typename boost::remove_const<T>::type;
0089 using iterator = T*;
0090 using const_iterator = value_type const*;
0091
0092 struct sentry_type
0093 {
0094 friend bool operator!=(iterator it, sentry_type) { return !!*it; }
0095 };
0096
0097 range (iterator b, iterator e =0) : base_type(b, e) {}
0098
0099 iterator end () { return base_type::end_ ? base_type::end_ : (base_type::end_ = base_type::begin_ + size()); }
0100 const_iterator end () const { return base_type::end_ ? base_type::end_ : (base_type::end_ = base_type::begin_ + size()); }
0101 sentry_type sentry () const { return sentry_type(); }
0102 std::size_t size () const { return std::char_traits<value_type>::length(base_type::begin_); }
0103 bool empty () const { return !*base_type::begin_; }
0104 };
0105 template<typename T>
0106 struct range<T* const, void> : public range<T*>
0107 {
0108 range (T* b, T* e =0) : range<T*>(b, e) {}
0109 };
0110 template <typename T, std::size_t N>
0111 struct range<T [N], void> : public range<T*>
0112 {
0113 range (T* b, T* e =0) : range<T*>(b, e) {}
0114 };
0115 }}
0116
0117 #endif