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