1 /////////////////////////////////////////////////////////////////////////////// 2 // results_cache.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 8 #ifndef BOOST_XPRESSIVE_DETAIL_CORE_RESULTS_CACHE_HPP_EAN_10_04_2005 9 #define BOOST_XPRESSIVE_DETAIL_CORE_RESULTS_CACHE_HPP_EAN_10_04_2005 10 11 // MS compatible compilers support #pragma once 12 #if defined(_MSC_VER) 13 # pragma once 14 #endif 15 16 #include <cstddef> 17 #include <boost/detail/workaround.hpp> 18 #include <boost/assert.hpp> 19 #include <boost/xpressive/detail/detail_fwd.hpp> 20 #include <boost/xpressive/detail/core/list.hpp> 21 #include <boost/xpressive/detail/core/access.hpp> 22 #include <boost/xpressive/match_results.hpp> 23 24 namespace boost { namespace xpressive { namespace detail 25 { 26 27 /////////////////////////////////////////////////////////////////////////////// 28 // nested_results 29 #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206)) 30 template<typename BidiIter> 31 struct nested_results 32 : detail::list<match_results<BidiIter> > 33 { 34 friend struct results_cache<BidiIter>; 35 friend struct match_results<BidiIter>; 36 }; 37 #else 38 template<typename BidiIter> 39 struct nested_results 40 : private detail::list<match_results<BidiIter> > 41 { 42 friend struct results_cache<BidiIter>; 43 friend struct xpressive::match_results<BidiIter>; 44 typedef list<xpressive::match_results<BidiIter> > base_type; 45 46 typedef typename base_type::iterator iterator; 47 typedef typename base_type::const_iterator const_iterator; 48 typedef typename base_type::pointer pointer; 49 typedef typename base_type::const_pointer const_pointer; 50 typedef typename base_type::reference reference; 51 typedef typename base_type::const_reference const_reference; 52 typedef typename base_type::size_type size_type; 53 using base_type::begin; 54 using base_type::end; 55 using base_type::size; 56 using base_type::empty; 57 using base_type::front; 58 using base_type::back; 59 }; 60 #endif 61 62 /////////////////////////////////////////////////////////////////////////////// 63 // results_cache 64 // 65 // cache storage for reclaimed match_results structs 66 template<typename BidiIter> 67 struct results_cache 68 { 69 typedef core_access<BidiIter> access; 70 append_newboost::xpressive::detail::results_cache71 match_results<BidiIter> &append_new(nested_results<BidiIter> &out) 72 { 73 if(this->cache_.empty()) 74 { 75 out.push_back(match_results<BidiIter>()); 76 } 77 else 78 { 79 BOOST_ASSERT(access::get_nested_results(this->cache_.back()).empty()); 80 out.splice(out.end(), this->cache_, --this->cache_.end()); 81 } 82 return out.back(); 83 } 84 85 // move the last match_results struct into the cache reclaim_lastboost::xpressive::detail::results_cache86 void reclaim_last(nested_results<BidiIter> &out) 87 { 88 BOOST_ASSERT(!out.empty()); 89 // first, reclaim any nested results 90 nested_results<BidiIter> &nested = access::get_nested_results(out.back()); 91 if(!nested.empty()) 92 { 93 this->reclaim_all(nested); 94 } 95 // then, reclaim the last match_results 96 this->cache_.splice(this->cache_.end(), out, --out.end()); 97 } 98 99 // move the last n match_results structs into the cache reclaim_last_nboost::xpressive::detail::results_cache100 void reclaim_last_n(nested_results<BidiIter> &out, std::size_t count) 101 { 102 for(; 0 != count; --count) 103 { 104 this->reclaim_last(out); 105 } 106 } 107 reclaim_allboost::xpressive::detail::results_cache108 void reclaim_all(nested_results<BidiIter> &out) 109 { 110 typedef typename nested_results<BidiIter>::iterator iter_type; 111 112 // first, recursively reclaim all the nested results 113 for(iter_type begin = out.begin(); begin != out.end(); ++begin) 114 { 115 nested_results<BidiIter> &nested = access::get_nested_results(*begin); 116 117 if(!nested.empty()) 118 { 119 this->reclaim_all(nested); 120 } 121 } 122 123 // next, reclaim the results themselves 124 this->cache_.splice(this->cache_.end(), out); 125 } 126 127 private: 128 129 nested_results<BidiIter> cache_; 130 }; 131 132 }}} // namespace boost::xpressive::detail 133 134 #endif 135