sub_match_vector.hpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // sub_match_vector.hpp
  3. //
  4. // Copyright 2008 Eric Niebler. Distributed under the Boost
  5. // Software License, Version 1.0. (See accompanying file
  6. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. #ifndef BOOST_XPRESSIVE_DETAIL_CORE_SUB_MATCH_VECTOR_HPP_EAN_10_04_2005
  8. #define BOOST_XPRESSIVE_DETAIL_CORE_SUB_MATCH_VECTOR_HPP_EAN_10_04_2005
  9. // MS compatible compilers support #pragma once
  10. #if defined(_MSC_VER)
  11. # pragma once
  12. #endif
  13. #include <boost/noncopyable.hpp>
  14. #include <boost/iterator_adaptors.hpp>
  15. #include <boost/xpressive/detail/detail_fwd.hpp>
  16. #include <boost/xpressive/detail/core/sub_match_impl.hpp>
  17. namespace boost { namespace xpressive { namespace detail
  18. {
  19. #if BOOST_ITERATOR_ADAPTORS_VERSION >= 0x0200
  20. //////////////////////////////////////////////////////////////////////////
  21. // sub_match_iterator
  22. //
  23. template<typename Value, typename MainIter>
  24. struct sub_match_iterator
  25. : iterator_adaptor
  26. <
  27. sub_match_iterator<Value, MainIter>
  28. , MainIter
  29. , Value
  30. , std::random_access_iterator_tag
  31. >
  32. {
  33. typedef iterator_adaptor
  34. <
  35. sub_match_iterator<Value, MainIter>
  36. , MainIter
  37. , Value
  38. , std::random_access_iterator_tag
  39. > base_t;
  40. sub_match_iterator(MainIter baseiter)
  41. : base_t(baseiter)
  42. {
  43. }
  44. };
  45. #endif
  46. //////////////////////////////////////////////////////////////////////////
  47. // sub_match_vector
  48. //
  49. template<typename BidiIter>
  50. struct sub_match_vector
  51. : private noncopyable
  52. {
  53. private:
  54. struct dummy { int i_; };
  55. typedef int dummy::*bool_type;
  56. public:
  57. typedef sub_match<BidiIter> value_type;
  58. typedef std::size_t size_type;
  59. typedef value_type const &const_reference;
  60. typedef const_reference reference;
  61. typedef typename iterator_difference<BidiIter>::type difference_type;
  62. typedef typename iterator_value<BidiIter>::type char_type;
  63. typedef typename sub_match<BidiIter>::string_type string_type;
  64. #if BOOST_ITERATOR_ADAPTORS_VERSION >= 0x0200
  65. typedef sub_match_iterator
  66. <
  67. value_type const
  68. , sub_match_impl<BidiIter> const *
  69. > const_iterator;
  70. #else
  71. typedef iterator_adaptor
  72. <
  73. sub_match_impl<BidiIter> const *
  74. , default_iterator_policies
  75. , value_type
  76. , value_type const &
  77. , value_type const *
  78. > const_iterator;
  79. #endif // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
  80. typedef const_iterator iterator;
  81. sub_match_vector()
  82. : size_(0)
  83. , sub_matches_(0)
  84. {
  85. }
  86. const_reference operator [](size_type index) const
  87. {
  88. static value_type const s_null;
  89. return (index >= this->size_)
  90. ? s_null
  91. : *static_cast<value_type const *>(&this->sub_matches_[ index ]);
  92. }
  93. size_type size() const
  94. {
  95. return this->size_;
  96. }
  97. bool empty() const
  98. {
  99. return 0 == this->size();
  100. }
  101. const_iterator begin() const
  102. {
  103. return const_iterator(this->sub_matches_);
  104. }
  105. const_iterator end() const
  106. {
  107. return const_iterator(this->sub_matches_ + this->size_);
  108. }
  109. operator bool_type() const
  110. {
  111. return (!this->empty() && (*this)[0].matched) ? &dummy::i_ : 0;
  112. }
  113. bool operator !() const
  114. {
  115. return this->empty() || !(*this)[0].matched;
  116. }
  117. void swap(sub_match_vector<BidiIter> &that)
  118. {
  119. std::swap(this->size_, that.size_);
  120. std::swap(this->sub_matches_, that.sub_matches_);
  121. }
  122. private:
  123. friend struct detail::core_access<BidiIter>;
  124. void init_(sub_match_impl<BidiIter> *sub_matches, size_type size)
  125. {
  126. this->size_ = size;
  127. this->sub_matches_ = sub_matches;
  128. }
  129. void init_(sub_match_impl<BidiIter> *sub_matches, size_type size, sub_match_vector<BidiIter> const &that)
  130. {
  131. BOOST_ASSERT(size == that.size_);
  132. this->size_ = size;
  133. this->sub_matches_ = sub_matches;
  134. std::copy(that.sub_matches_, that.sub_matches_ + that.size_, this->sub_matches_);
  135. }
  136. size_type size_;
  137. sub_match_impl<BidiIter> *sub_matches_;
  138. };
  139. }}} // namespace boost::xpressive::detail
  140. #endif