Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-15 09:31:07

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