Warning, file /include/boost/flyweight/refcounted.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_FLYWEIGHT_REFCOUNTED_HPP
0010 #define BOOST_FLYWEIGHT_REFCOUNTED_HPP
0011
0012 #if defined(_MSC_VER)
0013 #pragma once
0014 #endif
0015
0016 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
0017 #include <algorithm>
0018 #include <boost/config/workaround.hpp>
0019 #include <boost/core/invoke_swap.hpp>
0020 #include <boost/flyweight/refcounted_fwd.hpp>
0021 #include <boost/flyweight/tracking_tag.hpp>
0022 #include <boost/smart_ptr/detail/atomic_count.hpp>
0023
0024 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0025 #include <utility>
0026 #endif
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047 namespace boost{
0048
0049 namespace flyweights{
0050
0051 namespace detail{
0052
0053 template<typename Value,typename Key>
0054 class refcounted_value
0055 {
0056 public:
0057 explicit refcounted_value(const Value& x_):
0058 x(x_),ref(0),del_ref(0)
0059 {}
0060
0061 refcounted_value(const refcounted_value& r):
0062 x(r.x),ref(0),del_ref(0)
0063 {}
0064
0065 refcounted_value& operator=(const refcounted_value& r)
0066 {
0067 x=r.x;
0068 return *this;
0069 }
0070
0071 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0072 explicit refcounted_value(Value&& x_):
0073 x(std::move(x_)),ref(0),del_ref(0)
0074 {}
0075
0076 refcounted_value(refcounted_value&& r):
0077 x(std::move(r.x)),ref(0),del_ref(0)
0078 {}
0079
0080 refcounted_value& operator=(refcounted_value&& r)
0081 {
0082 x=std::move(r.x);
0083 return *this;
0084 }
0085 #endif
0086
0087 operator const Value&()const{return x;}
0088 operator const Key&()const{return x;}
0089
0090 #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
0091 private:
0092 template<typename,typename> friend class refcounted_handle;
0093 #endif
0094
0095 long count()const{return ref;}
0096 long add_ref()const{return ++ref;}
0097 bool release()const{return (--ref==0);}
0098
0099 void add_deleter()const{++del_ref;}
0100 bool release_deleter()const{return (--del_ref==0);}
0101
0102 private:
0103 Value x;
0104 mutable boost::detail::atomic_count ref;
0105 mutable long del_ref;
0106 };
0107
0108 template<typename Handle,typename TrackingHelper>
0109 class refcounted_handle
0110 {
0111 public:
0112 explicit refcounted_handle(const Handle& h_):h(h_)
0113 {
0114 if(TrackingHelper::entry(*this).add_ref()==1){
0115 TrackingHelper::entry(*this).add_deleter();
0116 }
0117 }
0118
0119 refcounted_handle(const refcounted_handle& x):h(x.h)
0120 {
0121 TrackingHelper::entry(*this).add_ref();
0122 }
0123
0124 refcounted_handle& operator=(refcounted_handle x)
0125 {
0126 this->swap(x);
0127 return *this;
0128 }
0129
0130 ~refcounted_handle()
0131 {
0132 if(TrackingHelper::entry(*this).release()){
0133 TrackingHelper::erase(*this,check_erase);
0134 }
0135 }
0136
0137 operator const Handle&()const{return h;}
0138
0139 void swap(refcounted_handle& x)
0140 {
0141 boost::core::invoke_swap(h,x.h);
0142 }
0143
0144 private:
0145 static bool check_erase(const refcounted_handle& x)
0146 {
0147 return TrackingHelper::entry(x).release_deleter();
0148 }
0149
0150 Handle h;
0151 };
0152
0153 template<typename Handle,typename TrackingHelper>
0154 void swap(
0155 refcounted_handle<Handle,TrackingHelper>& x,
0156 refcounted_handle<Handle,TrackingHelper>& y)
0157 {
0158 x.swap(y);
0159 }
0160
0161 }
0162
0163 #if BOOST_WORKAROUND(BOOST_MSVC,<=1500)
0164
0165
0166 }
0167
0168 template<typename Handle,typename TrackingHelper>
0169 void swap(
0170 ::boost::flyweights::detail::refcounted_handle<Handle,TrackingHelper>& x,
0171 ::boost::flyweights::detail::refcounted_handle<Handle,TrackingHelper>& y)
0172 {
0173 ::boost::flyweights::detail::swap(x,y);
0174 }
0175
0176 namespace flyweights{
0177 #endif
0178
0179 struct refcounted:tracking_marker
0180 {
0181 struct entry_type
0182 {
0183 template<typename Value,typename Key>
0184 struct apply
0185 {
0186 typedef detail::refcounted_value<Value,Key> type;
0187 };
0188 };
0189
0190 struct handle_type
0191 {
0192 template<typename Handle,typename TrackingHelper>
0193 struct apply
0194 {
0195 typedef detail::refcounted_handle<Handle,TrackingHelper> type;
0196 };
0197 };
0198 };
0199
0200 }
0201
0202 }
0203
0204 #endif