range.hpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // Copyright (c) 2009-2016 Vladimir Batov.
  2. // Use, modification and distribution are subject to the Boost Software License,
  3. // Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
  4. #ifndef BOOST_CONVERT_DETAIL_RANGE_HPP
  5. #define BOOST_CONVERT_DETAIL_RANGE_HPP
  6. #include <boost/convert/detail/has_member.hpp>
  7. #include <boost/convert/detail/char.hpp>
  8. #include <boost/utility/enable_if.hpp>
  9. #include <boost/range/iterator.hpp>
  10. namespace boost { namespace cnv
  11. {
  12. namespace detail
  13. {
  14. template<typename T, bool is_class> struct is_range : std::false_type {};
  15. template<typename T> struct is_range<T, /*is_class=*/true>
  16. {
  17. BOOST_DECLARE_HAS_MEMBER(has_begin, begin);
  18. BOOST_DECLARE_HAS_MEMBER( has_end, end);
  19. static bool const value = has_begin<T>::value && has_end<T>::value;
  20. };
  21. }
  22. template<typename T> struct is_range : detail::is_range<typename boost::remove_const<T>::type, boost::is_class<T>::value> {};
  23. template<typename T, typename enable =void> struct range;
  24. template<typename T, typename enable =void> struct iterator;
  25. template<typename T>
  26. struct iterator<T, typename enable_if<is_range<T> >::type>
  27. {
  28. typedef typename boost::range_iterator<T>::type type;
  29. typedef typename boost::range_iterator<T const>::type const_type;
  30. typedef typename boost::iterator_value<type>::type value_type;
  31. };
  32. template<typename T>
  33. struct iterator<T*, void>
  34. {
  35. typedef typename boost::remove_const<T>::type value_type;
  36. typedef T* type;
  37. typedef value_type const* const_type;
  38. };
  39. template<typename T>
  40. struct range_base
  41. {
  42. typedef typename cnv::iterator<T>::value_type value_type;
  43. typedef typename cnv::iterator<T>::type iterator;
  44. typedef typename cnv::iterator<T>::const_type const_iterator;
  45. typedef const_iterator sentry_type;
  46. iterator begin () { return begin_; }
  47. const_iterator begin () const { return begin_; }
  48. void operator++ () { ++begin_; }
  49. // void operator-- () { --end_; }
  50. protected:
  51. range_base (iterator b, iterator e) : begin_(b), end_(e) {}
  52. iterator begin_;
  53. iterator mutable end_;
  54. };
  55. template<typename T>
  56. struct range<T, typename enable_if<is_range<T> >::type> : public range_base<T>
  57. {
  58. typedef range this_type;
  59. typedef range_base<T> base_type;
  60. typedef typename base_type::iterator iterator;
  61. typedef typename base_type::const_iterator const_iterator;
  62. typedef const_iterator sentry_type;
  63. range (T& r) : base_type(r.begin(), r.end()) {}
  64. iterator end () { return base_type::end_; }
  65. const_iterator end () const { return base_type::end_; }
  66. sentry_type sentry () const { return base_type::end_; }
  67. std::size_t size () const { return base_type::end_ - base_type::begin_; }
  68. bool empty () const { return base_type::begin_ == base_type::end_; }
  69. };
  70. template<typename T>
  71. struct range<T*, typename enable_if<cnv::is_char<T> >::type> : public range_base<T*>
  72. {
  73. using this_type = range;
  74. using base_type = range_base<T*>;
  75. using value_type = typename boost::remove_const<T>::type;
  76. using iterator = T*;
  77. using const_iterator = value_type const*;
  78. struct sentry_type
  79. {
  80. friend bool operator!=(iterator it, sentry_type) { return !!*it; }
  81. };
  82. range (iterator b, iterator e =0) : base_type(b, e) {}
  83. iterator end () { return base_type::end_ ? base_type::end_ : (base_type::end_ = base_type::begin_ + size()); }
  84. const_iterator end () const { return base_type::end_ ? base_type::end_ : (base_type::end_ = base_type::begin_ + size()); }
  85. sentry_type sentry () const { return sentry_type(); }
  86. std::size_t size () const { return std::char_traits<value_type>::length(base_type::begin_); }
  87. bool empty () const { return !*base_type::begin_; }
  88. };
  89. template<typename T>
  90. struct range<T* const, void> : public range<T*>
  91. {
  92. range (T* b, T* e =0) : range<T*>(b, e) {}
  93. };
  94. template <typename T, std::size_t N>
  95. struct range<T [N], void> : public range<T*>
  96. {
  97. range (T* b, T* e =0) : range<T*>(b, e) {}
  98. };
  99. }}
  100. #endif // BOOST_CONVERT_DETAIL_RANGE_HPP