1 // Copyright (c) 2001 Daniel C. Nuffer 2 // Copyright (c) 2001-2011 Hartmut Kaiser 3 // 4 // Distributed under the Boost Software License, Version 1.0. (See accompanying 5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 7 #if !defined(BOOST_SPIRIT_ITERATOR_REF_COUNTED_POLICY_MAR_16_2007_1108AM) 8 #define BOOST_SPIRIT_ITERATOR_REF_COUNTED_POLICY_MAR_16_2007_1108AM 9 10 #include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp> 11 #include <boost/spirit/home/support/iterators/detail/multi_pass.hpp> 12 #if defined(BOOST_HAS_THREADS) 13 #include <boost/detail/atomic_count.hpp> 14 #endif 15 #include <cstdlib> 16 17 namespace boost { namespace spirit { namespace iterator_policies 18 { 19 /////////////////////////////////////////////////////////////////////////// 20 // class ref_counted 21 // Implementation of an OwnershipPolicy used by multi_pass. 22 // 23 // Implementation modified from RefCounted class from the Loki library by 24 // Andrei Alexandrescu. 25 /////////////////////////////////////////////////////////////////////////// 26 struct ref_counted 27 { 28 /////////////////////////////////////////////////////////////////////// 29 struct unique // : detail::default_ownership_policy 30 { swapboost::spirit::iterator_policies::ref_counted::unique31 void swap(unique&) {} 32 33 // clone is called when a copy of the iterator is made, so 34 // increment the ref-count. 35 template <typename MultiPass> cloneboost::spirit::iterator_policies::ref_counted::unique36 static void clone(MultiPass& mp) 37 { 38 if (0 != mp.shared()) 39 ++mp.shared()->count; 40 } 41 42 // called when a copy is deleted. Decrement the ref-count. Return 43 // value of true indicates that the last copy has been released. 44 template <typename MultiPass> releaseboost::spirit::iterator_policies::ref_counted::unique45 static bool release(MultiPass& mp) 46 { 47 return 0 != mp.shared() && 0 == --mp.shared()->count; 48 } 49 50 // returns true if there is only one iterator in existence. 51 // std_deque StoragePolicy will free it's buffered data if this 52 // returns true. 53 template <typename MultiPass> is_uniqueboost::spirit::iterator_policies::ref_counted::unique54 static bool is_unique(MultiPass const& mp) 55 { 56 return 0 == mp.shared() || 1 == mp.shared()->count; 57 } 58 59 template <typename MultiPass> destroyboost::spirit::iterator_policies::ref_counted::unique60 static void destroy(MultiPass&) {} 61 }; 62 63 //////////////////////////////////////////////////////////////////////// 64 struct shared 65 { sharedboost::spirit::iterator_policies::ref_counted::shared66 shared() : count(1) {} 67 68 #if defined(BOOST_HAS_THREADS) 69 boost::detail::atomic_count count; 70 #else 71 std::size_t count; 72 #endif 73 }; 74 75 }; 76 77 }}} 78 79 #endif 80