|
||||
File indexing completed on 2025-01-18 09:53:28
0001 // 0002 // Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.com) 0003 // 0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying 0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 0006 // 0007 // Official repository: https://github.com/boostorg/url 0008 // 0009 0010 #ifndef BOOST_URL_GRAMMAR_RECYCLED_HPP 0011 #define BOOST_URL_GRAMMAR_RECYCLED_HPP 0012 0013 #include <boost/url/detail/config.hpp> 0014 #include <boost/url/grammar/detail/recycled.hpp> 0015 #include <atomic> 0016 #include <cstddef> 0017 #include <type_traits> 0018 #include <stddef.h> // ::max_align_t 0019 0020 #if !defined(BOOST_URL_DISABLE_THREADS) 0021 # include <mutex> 0022 #endif 0023 0024 namespace boost { 0025 namespace urls { 0026 namespace grammar { 0027 0028 /** Provides an aligned storage buffer aligned for T 0029 */ 0030 #ifdef BOOST_URL_DOCS 0031 template<class T> 0032 struct aligned_storage 0033 { 0034 /** Return a pointer to the aligned storage area 0035 */ 0036 void* addr() noexcept; 0037 0038 /** Return a pointer to the aligned storage area 0039 */ 0040 void const* addr() const noexcept; 0041 }; 0042 #else 0043 template<class T> 0044 using aligned_storage = 0045 detail::aligned_storage_impl< 0046 detail::nearest_pow2(sizeof(T), 64), 0047 (alignof(::max_align_t) > alignof(T)) ? 0048 alignof(::max_align_t) : alignof(T)>; 0049 #endif 0050 0051 //------------------------------------------------ 0052 0053 /** A thread-safe collection of instances of T 0054 0055 Instances of this type may be used to control 0056 where recycled instances of T come from when 0057 used with @ref recycled_ptr. 0058 0059 @par Example 0060 @code 0061 static recycled< std::string > bin; 0062 0063 recycled_ptr< std::string > ps( bin ); 0064 0065 // Put the string into a known state 0066 ps->clear(); 0067 @endcode 0068 0069 @see 0070 @ref recycled_ptr. 0071 */ 0072 template<class T> 0073 class recycled 0074 { 0075 public: 0076 /** Destructor 0077 0078 All recycled instances of T are destroyed. 0079 Undefined behavior results if there are 0080 any @ref recycled_ptr which reference 0081 this recycle bin. 0082 */ 0083 ~recycled(); 0084 0085 /** Constructor 0086 */ 0087 constexpr recycled() = default; 0088 0089 private: 0090 template<class> 0091 friend class recycled_ptr; 0092 0093 struct U 0094 { 0095 T t; 0096 U* next = nullptr; 0097 0098 #if !defined(BOOST_URL_DISABLE_THREADS) 0099 std::atomic< 0100 std::size_t> refs; 0101 #else 0102 std::size_t refs; 0103 #endif 0104 0105 0106 U() 0107 : refs{1} 0108 { 0109 } 0110 }; 0111 0112 struct report; 0113 0114 U* acquire(); 0115 void release(U* u) noexcept; 0116 0117 U* head_ = nullptr; 0118 0119 #if !defined(BOOST_URL_DISABLE_THREADS) 0120 std::mutex m_; 0121 #endif 0122 }; 0123 0124 //------------------------------------------------ 0125 0126 /** A pointer to shared instance of T 0127 0128 This is a smart pointer container which can 0129 acquire shared ownership of an instance of 0130 `T` upon or after construction. The instance 0131 is guaranteed to be in a valid, but unknown 0132 state. Every recycled pointer references 0133 a valid recycle bin. 0134 0135 @par Example 0136 @code 0137 static recycled< std::string > bin; 0138 0139 recycled_ptr< std::string > ps( bin ); 0140 0141 // Put the string into a known state 0142 ps->clear(); 0143 @endcode 0144 0145 @tparam T the type of object to 0146 acquire, which must be 0147 <em>DefaultConstructible</em>. 0148 */ 0149 template<class T> 0150 class recycled_ptr 0151 { 0152 // T must be default constructible! 0153 static_assert( 0154 std::is_default_constructible<T>::value, 0155 "T must be DefaultConstructible"); 0156 0157 friend class recycled<T>; 0158 0159 using B = recycled<T>; 0160 using U = typename B::U; 0161 0162 B* bin_ = nullptr; 0163 U* p_ = nullptr; 0164 0165 public: 0166 /** Destructor 0167 0168 If this is not empty, shared ownership 0169 of the pointee is released. If this was 0170 the last reference, the object is 0171 returned to the original recycle bin. 0172 0173 @par Effects 0174 @code 0175 this->release(); 0176 @endcode 0177 */ 0178 ~recycled_ptr(); 0179 0180 /** Constructor 0181 0182 Upon construction, this acquires 0183 exclusive access to an object of type 0184 `T` which is either recycled from the 0185 specified bin, or newly allocated. 0186 The object is in an unknown but 0187 valid state. 0188 0189 @par Example 0190 @code 0191 static recycled< std::string > bin; 0192 0193 recycled_ptr< std::string > ps( bin ); 0194 0195 // Put the string into a known state 0196 ps->clear(); 0197 @endcode 0198 0199 @par Postconditions 0200 @code 0201 &this->bin() == &bin && ! this->empty() 0202 @endcode 0203 0204 @param bin The recycle bin to use 0205 0206 @see 0207 @ref recycled. 0208 */ 0209 explicit 0210 recycled_ptr(recycled<T>& bin); 0211 0212 /** Constructor 0213 0214 After construction, this is empty and 0215 refers to the specified recycle bin. 0216 0217 @par Example 0218 @code 0219 static recycled< std::string > bin; 0220 0221 recycled_ptr< std::string > ps( bin, nullptr ); 0222 0223 // Acquire a string and put it into a known state 0224 ps->acquire(); 0225 ps->clear(); 0226 @endcode 0227 0228 @par Postconditions 0229 @code 0230 &this->bin() == &bin && this->empty() 0231 @endcode 0232 0233 @par Exception Safety 0234 Throws nothing. 0235 0236 @param bin The recycle bin to use 0237 0238 @see 0239 @ref acquire, 0240 @ref recycled, 0241 @ref release. 0242 */ 0243 recycled_ptr( 0244 recycled<T>& bin, 0245 std::nullptr_t) noexcept; 0246 0247 /** Constructor 0248 0249 Upon construction, this acquires 0250 exclusive access to an object of type 0251 `T` which is either recycled from a 0252 global recycle bin, or newly allocated. 0253 The object is in an unknown but 0254 valid state. 0255 0256 @par Example 0257 @code 0258 recycled_ptr< std::string > ps; 0259 0260 // Put the string into a known state 0261 ps->clear(); 0262 @endcode 0263 0264 @par Postconditions 0265 @code 0266 &this->bin() != nullptr && ! this->empty() 0267 @endcode 0268 0269 @see 0270 @ref recycled. 0271 */ 0272 recycled_ptr(); 0273 0274 /** Constructor 0275 0276 After construction, this is empty 0277 and refers to a global recycle bin. 0278 0279 @par Example 0280 @code 0281 recycled_ptr< std::string > ps( nullptr ); 0282 0283 // Acquire a string and put it into a known state 0284 ps->acquire(); 0285 ps->clear(); 0286 @endcode 0287 0288 @par Postconditions 0289 @code 0290 &this->bin() != nullptr && this->empty() 0291 @endcode 0292 0293 @par Exception Safety 0294 Throws nothing. 0295 0296 @see 0297 @ref acquire, 0298 @ref recycled, 0299 @ref release. 0300 */ 0301 recycled_ptr( 0302 std::nullptr_t) noexcept; 0303 0304 /** Constructor 0305 0306 If `other` references an object, the 0307 newly constructed pointer acquires 0308 shared ownership. Otherwise this is 0309 empty. The new pointer references 0310 the same recycle bin as `other`. 0311 0312 @par Postconditions 0313 @code 0314 &this->bin() == &other->bin() && this->get() == other.get() 0315 @endcode 0316 0317 @par Exception Safety 0318 Throws nothing. 0319 0320 @param other The pointer to copy 0321 */ 0322 recycled_ptr( 0323 recycled_ptr const& other) noexcept; 0324 0325 /** Constructor 0326 0327 If `other` references an object, 0328 ownership is transferred including 0329 a reference to the recycle bin. After 0330 the move, the moved-from object is empty. 0331 0332 @par Postconditions 0333 @code 0334 &this->bin() == &other->bin() && ! this->empty() && other.empty() 0335 @endcode 0336 0337 @par Exception Safety 0338 Throws nothing. 0339 0340 @param other The pointer to move from 0341 */ 0342 recycled_ptr( 0343 recycled_ptr&& other) noexcept; 0344 0345 /** Assignment 0346 0347 If `other` references an object, 0348 ownership is transferred including 0349 a reference to the recycle bin. After 0350 the move, the moved-from object is empty. 0351 0352 @par Effects 0353 @code 0354 this->release() 0355 @endcode 0356 0357 @par Postconditions 0358 @code 0359 &this->bin() == &other->bin() 0360 @endcode 0361 0362 @par Exception Safety 0363 Throws nothing. 0364 0365 @param other The pointer to move from 0366 */ 0367 recycled_ptr& 0368 operator=( 0369 recycled_ptr&& other) noexcept; 0370 0371 /** Assignment 0372 0373 If `other` references an object, 0374 this acquires shared ownership and 0375 references the same recycle bin as 0376 `other`. The previous object if any 0377 is released. 0378 0379 @par Effects 0380 @code 0381 this->release() 0382 @endcode 0383 0384 @par Postconditions 0385 @code 0386 &this->bin() == &other->bin() && this->get() == other.get() 0387 @endcode 0388 0389 @par Exception Safety 0390 Throws nothing. 0391 0392 @param other The pointer to copy from 0393 */ 0394 recycled_ptr& 0395 operator=( 0396 recycled_ptr const& other) noexcept; 0397 0398 /** Return true if this does not reference an object 0399 0400 @par Exception Safety 0401 Throws nothing. 0402 */ 0403 bool 0404 empty() const noexcept 0405 { 0406 return p_ == nullptr; 0407 } 0408 0409 /** Return true if this references an object 0410 0411 @par Effects 0412 @code 0413 return ! this->empty(); 0414 @endcode 0415 0416 @par Exception Safety 0417 Throws nothing. 0418 */ 0419 explicit 0420 operator bool() const noexcept 0421 { 0422 return p_ != nullptr; 0423 } 0424 0425 /** Return the referenced recycle bin 0426 0427 @par Exception Safety 0428 Throws nothing. 0429 */ 0430 recycled<T>& 0431 bin() const noexcept 0432 { 0433 return *bin_; 0434 } 0435 0436 /** Return the referenced object 0437 0438 If this is empty, `nullptr` is returned. 0439 0440 @par Exception Safety 0441 Throws nothing. 0442 */ 0443 T* get() const noexcept 0444 { 0445 return &p_->t; 0446 } 0447 0448 /** Return the referenced object 0449 0450 If this is empty, `nullptr` is returned. 0451 0452 @par Exception Safety 0453 Throws nothing. 0454 */ 0455 T* operator->() const noexcept 0456 { 0457 return get(); 0458 } 0459 0460 /** Return the referenced object 0461 0462 @par Preconditions 0463 @code 0464 not this->empty() 0465 @endcode 0466 */ 0467 T& operator*() const noexcept 0468 { 0469 return *get(); 0470 } 0471 0472 /** Return the referenced object 0473 0474 If this references an object, it is 0475 returned. Otherwise, exclusive ownership 0476 of a new object of type `T` is acquired 0477 and returned. 0478 0479 @par Postconditions 0480 @code 0481 not this->empty() 0482 @endcode 0483 */ 0484 T& acquire(); 0485 0486 /** Release the referenced object 0487 0488 If this references an object, it is 0489 released to the referenced recycle bin. 0490 The pointer continues to reference 0491 the same recycle bin. 0492 0493 @par Postconditions 0494 @code 0495 this->empty() 0496 @endcode 0497 0498 @par Exception Safety 0499 Throws nothing. 0500 */ 0501 void release() noexcept; 0502 }; 0503 0504 } // grammar 0505 } // urls 0506 } // boost 0507 0508 #include <boost/url/grammar/impl/recycled.hpp> 0509 0510 #endif
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |