123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- //
- // Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.com)
- //
- // 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)
- //
- // Official repository: https://github.com/boostorg/url
- //
- #ifndef BOOST_URL_GRAMMAR_IMPL_RECYCLED_PTR_HPP
- #define BOOST_URL_GRAMMAR_IMPL_RECYCLED_PTR_HPP
- #include <boost/assert.hpp>
- namespace boost {
- namespace urls {
- namespace grammar {
- //------------------------------------------------
- template<class T>
- recycled<T>::
- ~recycled()
- {
- std::size_t n = 0;
- // VFALCO we should probably deallocate
- // in reverse order of allocation but
- // that requires a doubly-linked list.
- auto it = head_;
- while(it)
- {
- ++n;
- auto next = it->next;
- BOOST_ASSERT(
- it->refs == 0);
- delete it;
- it = next;
- }
- detail::recycled_remove(
- sizeof(U) * n);
- }
- template<class T>
- auto
- recycled<T>::
- acquire() ->
- U*
- {
- U* p;
- {
- #if !defined(BOOST_URL_DISABLE_THREADS)
- std::lock_guard<
- std::mutex> lock(m_);
- #endif
- p = head_;
- if(p)
- {
- // reuse
- head_ = head_->next;
- detail::recycled_remove(
- sizeof(U));
- ++p->refs;
- }
- else
- {
- p = new U;
- }
- }
- BOOST_ASSERT(p->refs == 1);
- return p;
- }
- template<class T>
- void
- recycled<T>::
- release(U* u) noexcept
- {
- if(--u->refs != 0)
- return;
- {
- #if !defined(BOOST_URL_DISABLE_THREADS)
- std::lock_guard<
- std::mutex> lock(m_);
- #endif
- u->next = head_;
- head_ = u;
- }
- detail::recycled_add(
- sizeof(U));
- }
- //------------------------------------------------
- template<class T>
- recycled_ptr<T>::
- ~recycled_ptr()
- {
- if(p_)
- bin_->release(p_);
- }
- template<class T>
- recycled_ptr<T>::
- recycled_ptr(
- recycled<T>& bin)
- : bin_(&bin)
- , p_(bin.acquire())
- {
- }
- template<class T>
- recycled_ptr<T>::
- recycled_ptr(
- recycled<T>& bin,
- std::nullptr_t) noexcept
- : bin_(&bin)
- {
- }
- template<class T>
- recycled_ptr<T>::
- recycled_ptr()
- : recycled_ptr(nullptr)
- {
- p_ = bin_->acquire();
- }
- template<class T>
- recycled_ptr<T>::
- recycled_ptr(
- std::nullptr_t) noexcept
- : recycled_ptr([]() -> B&
- {
- // VFALCO need guaranteed constexpr-init
- static B r;
- return r;
- }(), nullptr)
- {
- }
- template<class T>
- recycled_ptr<T>::
- recycled_ptr(
- recycled_ptr const& other) noexcept
- : bin_(other.bin_)
- , p_(other.p_)
- {
- if(p_)
- ++p_->refs;
- }
- template<class T>
- recycled_ptr<T>::
- recycled_ptr(
- recycled_ptr&& other) noexcept
- : bin_(other.bin_)
- , p_(other.p_)
- {
- other.p_ = nullptr;
- }
- template<class T>
- auto
- recycled_ptr<T>::
- operator=(
- recycled_ptr&& other) noexcept ->
- recycled_ptr&
- {
- BOOST_ASSERT(
- bin_ == other.bin_);
- if(p_)
- bin_->release(p_);
- p_ = other.p_;
- other.p_ = nullptr;
- return *this;
- }
- template<class T>
- auto
- recycled_ptr<T>::
- operator=(
- recycled_ptr const& other) noexcept ->
- recycled_ptr&
- {
- BOOST_ASSERT(
- bin_ == other.bin_);
- if(p_)
- bin_->release(p_);
- p_ = other.p_;
- if(p_)
- ++p_->refs;
- return *this;
- }
- template<class T>
- T&
- recycled_ptr<T>::
- acquire()
- {
- if(! p_)
- p_ = bin_->acquire();
- return p_->t;
- }
- template<class T>
- void
- recycled_ptr<T>::
- release() noexcept
- {
- if(p_)
- {
- bin_->release(p_);
- p_ = nullptr;
- }
- }
- } // grammar
- } // urls
- } // boost
- #endif
|