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