File indexing completed on 2025-01-18 09:53:49
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_XPRESSIVE_DETAIL_CORE_RESULTS_CACHE_HPP_EAN_10_04_2005
0009 #define BOOST_XPRESSIVE_DETAIL_CORE_RESULTS_CACHE_HPP_EAN_10_04_2005
0010
0011
0012 #if defined(_MSC_VER)
0013 # pragma once
0014 #endif
0015
0016 #include <cstddef>
0017 #include <boost/detail/workaround.hpp>
0018 #include <boost/assert.hpp>
0019 #include <boost/xpressive/detail/detail_fwd.hpp>
0020 #include <boost/xpressive/detail/core/list.hpp>
0021 #include <boost/xpressive/detail/core/access.hpp>
0022 #include <boost/xpressive/match_results.hpp>
0023
0024 namespace boost { namespace xpressive { namespace detail
0025 {
0026
0027
0028
0029 #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206))
0030 template<typename BidiIter>
0031 struct nested_results
0032 : detail::list<match_results<BidiIter> >
0033 {
0034 friend struct results_cache<BidiIter>;
0035 friend struct match_results<BidiIter>;
0036 };
0037 #else
0038 template<typename BidiIter>
0039 struct nested_results
0040 : private detail::list<match_results<BidiIter> >
0041 {
0042 friend struct results_cache<BidiIter>;
0043 friend struct xpressive::match_results<BidiIter>;
0044 typedef list<xpressive::match_results<BidiIter> > base_type;
0045
0046 typedef typename base_type::iterator iterator;
0047 typedef typename base_type::const_iterator const_iterator;
0048 typedef typename base_type::pointer pointer;
0049 typedef typename base_type::const_pointer const_pointer;
0050 typedef typename base_type::reference reference;
0051 typedef typename base_type::const_reference const_reference;
0052 typedef typename base_type::size_type size_type;
0053 using base_type::begin;
0054 using base_type::end;
0055 using base_type::size;
0056 using base_type::empty;
0057 using base_type::front;
0058 using base_type::back;
0059 };
0060 #endif
0061
0062
0063
0064
0065
0066 template<typename BidiIter>
0067 struct results_cache
0068 {
0069 typedef core_access<BidiIter> access;
0070
0071 match_results<BidiIter> &append_new(nested_results<BidiIter> &out)
0072 {
0073 if(this->cache_.empty())
0074 {
0075 out.push_back(match_results<BidiIter>());
0076 }
0077 else
0078 {
0079 BOOST_ASSERT(access::get_nested_results(this->cache_.back()).empty());
0080 out.splice(out.end(), this->cache_, --this->cache_.end());
0081 }
0082 return out.back();
0083 }
0084
0085
0086 void reclaim_last(nested_results<BidiIter> &out)
0087 {
0088 BOOST_ASSERT(!out.empty());
0089
0090 nested_results<BidiIter> &nested = access::get_nested_results(out.back());
0091 if(!nested.empty())
0092 {
0093 this->reclaim_all(nested);
0094 }
0095
0096 this->cache_.splice(this->cache_.end(), out, --out.end());
0097 }
0098
0099
0100 void reclaim_last_n(nested_results<BidiIter> &out, std::size_t count)
0101 {
0102 for(; 0 != count; --count)
0103 {
0104 this->reclaim_last(out);
0105 }
0106 }
0107
0108 void reclaim_all(nested_results<BidiIter> &out)
0109 {
0110 typedef typename nested_results<BidiIter>::iterator iter_type;
0111
0112
0113 for(iter_type begin = out.begin(); begin != out.end(); ++begin)
0114 {
0115 nested_results<BidiIter> &nested = access::get_nested_results(*begin);
0116
0117 if(!nested.empty())
0118 {
0119 this->reclaim_all(nested);
0120 }
0121 }
0122
0123
0124 this->cache_.splice(this->cache_.end(), out);
0125 }
0126
0127 private:
0128
0129 nested_results<BidiIter> cache_;
0130 };
0131
0132 }}}
0133
0134 #endif