Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:49

0001 ///////////////////////////////////////////////////////////////////////////////
0002 // results_cache.hpp
0003 //
0004 //  Copyright 2008 Eric Niebler. Distributed under the Boost
0005 //  Software License, Version 1.0. (See accompanying file
0006 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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 // MS compatible compilers support #pragma once
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     // nested_results
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     // results_cache
0064     //
0065     //   cache storage for reclaimed match_results structs
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         // move the last match_results struct into the cache
0086         void reclaim_last(nested_results<BidiIter> &out)
0087         {
0088             BOOST_ASSERT(!out.empty());
0089             // first, reclaim any nested results
0090             nested_results<BidiIter> &nested = access::get_nested_results(out.back());
0091             if(!nested.empty())
0092             {
0093                 this->reclaim_all(nested);
0094             }
0095             // then, reclaim the last match_results
0096             this->cache_.splice(this->cache_.end(), out, --out.end());
0097         }
0098 
0099         // move the last n match_results structs into the cache
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             // first, recursively reclaim all the nested results
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             // next, reclaim the results themselves
0124             this->cache_.splice(this->cache_.end(), out);
0125         }
0126 
0127     private:
0128 
0129         nested_results<BidiIter> cache_;
0130     };
0131 
0132 }}} // namespace boost::xpressive::detail
0133 
0134 #endif