Server IP : 172.67.216.182 / Your IP : 162.158.106.62 Web Server : Apache System : Linux krdc-ubuntu-s-2vcpu-4gb-amd-blr1-01.localdomain 5.15.0-142-generic #152-Ubuntu SMP Mon May 19 10:54:31 UTC 2025 x86_64 User : www ( 1000) PHP Version : 7.4.33 Disable Function : passthru,exec,system,putenv,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /www/server/mysql/src/boost/boost_1_59_0/boost/flyweight/ |
Upload File : |
/* Copyright 2006-2014 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/flyweight for library home page. */ #ifndef BOOST_FLYWEIGHT_REFCOUNTED_HPP #define BOOST_FLYWEIGHT_REFCOUNTED_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <algorithm> #include <boost/detail/atomic_count.hpp> #include <boost/detail/workaround.hpp> #include <boost/flyweight/refcounted_fwd.hpp> #include <boost/flyweight/tracking_tag.hpp> #include <boost/utility/swap.hpp> #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) #include <utility> #endif /* Refcounting tracking policy. * The implementation deserves some explanation; values are equipped with two * reference counts: * - a regular count of active references * - a deleter count * It looks like a value can be erased when the number of references reaches * zero, but this condition alone can lead to data races: * - Thread A detaches the last reference to x and is preempted. * - Thread B looks for x, finds it and attaches a reference to it. * - Thread A resumes and proceeds with erasing x, leaving a dangling * reference in thread B. * Here is where the deleter count comes into play. This count is * incremented when the reference count changes from 0 to 1, and decremented * when a thread is about to check a value for erasure; it can be seen that a * value is effectively erasable only when the deleter count goes down to 0 * (unless there are dangling references due to abnormal program termination, * for instance if std::exit is called). */ namespace boost{ namespace flyweights{ namespace detail{ template<typename Value,typename Key> class refcounted_value { public: explicit refcounted_value(const Value& x_): x(x_),ref(0),del_ref(0) {} refcounted_value(const refcounted_value& r): x(r.x),ref(0),del_ref(0) {} refcounted_value& operator=(const refcounted_value& r) { x=r.x; return *this; } #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) explicit refcounted_value(Value&& x_): x(std::move(x_)),ref(0),del_ref(0) {} refcounted_value(refcounted_value&& r): x(std::move(r.x)),ref(0),del_ref(0) {} refcounted_value& operator=(refcounted_value&& r) { x=std::move(r.x); return *this; } #endif operator const Value&()const{return x;} operator const Key&()const{return x;} #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) private: template<typename,typename> friend class refcounted_handle; #endif long count()const{return ref;} long add_ref()const{return ++ref;} bool release()const{return (--ref==0);} void add_deleter()const{++del_ref;} bool release_deleter()const{return (--del_ref==0);} private: Value x; mutable boost::detail::atomic_count ref; mutable long del_ref; }; template<typename Handle,typename TrackingHelper> class refcounted_handle { public: explicit refcounted_handle(const Handle& h_):h(h_) { if(TrackingHelper::entry(*this).add_ref()==1){ TrackingHelper::entry(*this).add_deleter(); } } refcounted_handle(const refcounted_handle& x):h(x.h) { TrackingHelper::entry(*this).add_ref(); } refcounted_handle& operator=(refcounted_handle x) { this->swap(x); return *this; } ~refcounted_handle() { if(TrackingHelper::entry(*this).release()){ TrackingHelper::erase(*this,check_erase); } } operator const Handle&()const{return h;} void swap(refcounted_handle& x) { std::swap(h,x.h); } private: static bool check_erase(const refcounted_handle& x) { return TrackingHelper::entry(x).release_deleter(); } Handle h; }; template<typename Handle,typename TrackingHelper> void swap( refcounted_handle<Handle,TrackingHelper>& x, refcounted_handle<Handle,TrackingHelper>& y) { x.swap(y); } } /* namespace flyweights::detail */ #if BOOST_WORKAROUND(BOOST_MSVC,<=1500) /* swap lookup by boost::swap fails under obscure circumstances */ } /* namespace flyweights */ template<typename Handle,typename TrackingHelper> void swap( ::boost::flyweights::detail::refcounted_handle<Handle,TrackingHelper>& x, ::boost::flyweights::detail::refcounted_handle<Handle,TrackingHelper>& y) { ::boost::flyweights::detail::swap(x,y); } namespace flyweights{ #endif struct refcounted:tracking_marker { struct entry_type { template<typename Value,typename Key> struct apply { typedef detail::refcounted_value<Value,Key> type; }; }; struct handle_type { template<typename Handle,typename TrackingHelper> struct apply { typedef detail::refcounted_handle<Handle,TrackingHelper> type; }; }; }; } /* namespace flyweights */ } /* namespace boost */ #endif