Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:50:36

0001 /*
0002 Copyright 2017-2019 Glen Joseph Fernandes
0003 (glenjofe@gmail.com)
0004 
0005 Distributed under the Boost Software License, Version 1.0.
0006 (http://www.boost.org/LICENSE_1_0.txt)
0007 */
0008 #ifndef BOOST_SMART_PTR_ALLOCATE_LOCAL_SHARED_ARRAY_HPP
0009 #define BOOST_SMART_PTR_ALLOCATE_LOCAL_SHARED_ARRAY_HPP
0010 
0011 #include <boost/smart_ptr/allocate_shared_array.hpp>
0012 #include <boost/smart_ptr/local_shared_ptr.hpp>
0013 #include <boost/smart_ptr/detail/sp_type_traits.hpp>
0014 #include <type_traits>
0015 
0016 namespace boost {
0017 namespace detail {
0018 
0019 class BOOST_SYMBOL_VISIBLE lsp_array_base
0020     : public local_counted_base {
0021 public:
0022     void set(sp_counted_base* base) noexcept {
0023         count_ = shared_count(base);
0024     }
0025 
0026     void local_cb_destroy() noexcept override {
0027         shared_count().swap(count_);
0028     }
0029 
0030     shared_count local_cb_get_shared_count() const
0031         noexcept override {
0032         return count_;
0033     }
0034 
0035 private:
0036     shared_count count_;
0037 };
0038 
0039 template<class A>
0040 class lsp_array_state
0041     : public sp_array_state<A> {
0042 public:
0043     template<class U>
0044     lsp_array_state(const U& other, std::size_t size) noexcept
0045         : sp_array_state<A>(other, size) { }
0046 
0047     lsp_array_base& base() noexcept {
0048         return base_;
0049     }
0050 
0051 private:
0052     lsp_array_base base_;
0053 };
0054 
0055 template<class A, std::size_t N>
0056 class lsp_size_array_state
0057     : public sp_size_array_state<A, N> {
0058 public:
0059     template<class U>
0060     lsp_size_array_state(const U& other, std::size_t size) noexcept
0061         : sp_size_array_state<A, N>(other, size) { }
0062 
0063     lsp_array_base& base() noexcept {
0064         return base_;
0065     }
0066 
0067 private:
0068     lsp_array_base base_;
0069 };
0070 
0071 } /* detail */
0072 
0073 template<class T, class A>
0074 inline typename std::enable_if<detail::sp_is_unbounded_array<T>::value,
0075     local_shared_ptr<T> >::type
0076 allocate_local_shared(const A& allocator, std::size_t count)
0077 {
0078     typedef typename detail::sp_array_element<T>::type element;
0079     typedef typename allocator_rebind<A, element>::type other;
0080     typedef detail::lsp_array_state<other> state;
0081     typedef detail::sp_array_base<state> base;
0082     detail::sp_array_result<other, base> result(allocator, count);
0083     base* node = result.get();
0084     element* start = detail::sp_array_start<element>(node);
0085     ::new(static_cast<void*>(node)) base(allocator, start, count);
0086     detail::lsp_array_base& local = node->state().base();
0087     local.set(node);
0088     result.release();
0089     return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start,
0090         &local);
0091 }
0092 
0093 template<class T, class A>
0094 inline typename std::enable_if<detail::sp_is_bounded_array<T>::value,
0095     local_shared_ptr<T> >::type
0096 allocate_local_shared(const A& allocator)
0097 {
0098     enum {
0099         count = std::extent<T>::value
0100     };
0101     typedef typename detail::sp_array_element<T>::type element;
0102     typedef typename allocator_rebind<A, element>::type other;
0103     typedef detail::lsp_size_array_state<other, count> state;
0104     typedef detail::sp_array_base<state> base;
0105     detail::sp_array_result<other, base> result(allocator, count);
0106     base* node = result.get();
0107     element* start = detail::sp_array_start<element>(node);
0108     ::new(static_cast<void*>(node)) base(allocator, start, count);
0109     detail::lsp_array_base& local = node->state().base();
0110     local.set(node);
0111     result.release();
0112     return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start,
0113         &local);
0114 }
0115 
0116 template<class T, class A>
0117 inline typename std::enable_if<detail::sp_is_unbounded_array<T>::value,
0118     local_shared_ptr<T> >::type
0119 allocate_local_shared(const A& allocator, std::size_t count,
0120     const typename std::remove_extent<T>::type& value)
0121 {
0122     typedef typename detail::sp_array_element<T>::type element;
0123     typedef typename allocator_rebind<A, element>::type other;
0124     typedef detail::lsp_array_state<other> state;
0125     typedef detail::sp_array_base<state> base;
0126     detail::sp_array_result<other, base> result(allocator, count);
0127     base* node = result.get();
0128     element* start = detail::sp_array_start<element>(node);
0129     ::new(static_cast<void*>(node)) base(allocator, start, count, value);
0130     detail::lsp_array_base& local = node->state().base();
0131     local.set(node);
0132     result.release();
0133     return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start,
0134         &local);
0135 }
0136 
0137 template<class T, class A>
0138 inline typename std::enable_if<detail::sp_is_bounded_array<T>::value,
0139     local_shared_ptr<T> >::type
0140 allocate_local_shared(const A& allocator,
0141     const typename std::remove_extent<T>::type& value)
0142 {
0143     enum {
0144         count = std::extent<T>::value
0145     };
0146     typedef typename detail::sp_array_element<T>::type element;
0147     typedef typename allocator_rebind<A, element>::type other;
0148     typedef detail::lsp_size_array_state<other, count> state;
0149     typedef detail::sp_array_base<state> base;
0150     detail::sp_array_result<other, base> result(allocator, count);
0151     base* node = result.get();
0152     element* start = detail::sp_array_start<element>(node);
0153     ::new(static_cast<void*>(node)) base(allocator, start, count, value);
0154     detail::lsp_array_base& local = node->state().base();
0155     local.set(node);
0156     result.release();
0157     return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start,
0158         &local);
0159 }
0160 
0161 template<class T, class A>
0162 inline typename std::enable_if<detail::sp_is_unbounded_array<T>::value,
0163     local_shared_ptr<T> >::type
0164 allocate_local_shared_noinit(const A& allocator, std::size_t count)
0165 {
0166     return boost::allocate_local_shared<T>(boost::noinit_adapt(allocator),
0167         count);
0168 }
0169 
0170 template<class T, class A>
0171 inline typename std::enable_if<detail::sp_is_bounded_array<T>::value,
0172     local_shared_ptr<T> >::type
0173 allocate_local_shared_noinit(const A& allocator)
0174 {
0175     return boost::allocate_local_shared<T>(boost::noinit_adapt(allocator));
0176 }
0177 
0178 } /* boost */
0179 
0180 #endif