1 #ifndef MAPBOX_UTIL_RECURSIVE_WRAPPER_HPP 2 #define MAPBOX_UTIL_RECURSIVE_WRAPPER_HPP 3 4 // Based on variant/recursive_wrapper.hpp from boost. 5 // 6 // Original license: 7 // 8 // Copyright (c) 2002-2003 9 // Eric Friedman, Itay Maman 10 // 11 // Distributed under the Boost Software License, Version 1.0. (See 12 // accompanying file LICENSE_1_0.txt or copy at 13 // http://www.boost.org/LICENSE_1_0.txt) 14 15 #include <cassert> 16 #include <utility> 17 18 namespace mapbox { 19 namespace util { 20 21 template <typename T> 22 class recursive_wrapper 23 { 24 25 T* p_; 26 assign(T const & rhs)27 void assign(T const& rhs) 28 { 29 this->get() = rhs; 30 } 31 32 public: 33 using type = T; 34 35 /** 36 * Default constructor default initializes the internally stored value. 37 * For POD types this means nothing is done and the storage is 38 * uninitialized. 39 * 40 * @throws std::bad_alloc if there is insufficient memory for an object 41 * of type T. 42 * @throws any exception thrown by the default constructur of T. 43 */ recursive_wrapper()44 recursive_wrapper() 45 : p_(new T){} 46 ~recursive_wrapper()47 ~recursive_wrapper() noexcept { delete p_; } 48 recursive_wrapper(recursive_wrapper const & operand)49 recursive_wrapper(recursive_wrapper const& operand) 50 : p_(new T(operand.get())) {} 51 recursive_wrapper(T const & operand)52 recursive_wrapper(T const& operand) 53 : p_(new T(operand)) {} 54 recursive_wrapper(recursive_wrapper && operand)55 recursive_wrapper(recursive_wrapper&& operand) 56 : p_(new T(std::move(operand.get()))) {} 57 recursive_wrapper(T && operand)58 recursive_wrapper(T&& operand) 59 : p_(new T(std::move(operand))) {} 60 operator =(recursive_wrapper const & rhs)61 inline recursive_wrapper& operator=(recursive_wrapper const& rhs) 62 { 63 assign(rhs.get()); 64 return *this; 65 } 66 operator =(T const & rhs)67 inline recursive_wrapper& operator=(T const& rhs) 68 { 69 assign(rhs); 70 return *this; 71 } 72 swap(recursive_wrapper & operand)73 inline void swap(recursive_wrapper& operand) noexcept 74 { 75 T* temp = operand.p_; 76 operand.p_ = p_; 77 p_ = temp; 78 } 79 operator =(recursive_wrapper && rhs)80 recursive_wrapper& operator=(recursive_wrapper&& rhs) noexcept 81 { 82 swap(rhs); 83 return *this; 84 } 85 operator =(T && rhs)86 recursive_wrapper& operator=(T&& rhs) 87 { 88 get() = std::move(rhs); 89 return *this; 90 } 91 get()92 T& get() 93 { 94 assert(p_); 95 return *get_pointer(); 96 } 97 get() const98 T const& get() const 99 { 100 assert(p_); 101 return *get_pointer(); 102 } 103 get_pointer()104 T* get_pointer() { return p_; } 105 get_pointer() const106 const T* get_pointer() const { return p_; } 107 operator T const&() const108 operator T const&() const { return this->get(); } 109 operator T&()110 operator T&() { return this->get(); } 111 112 }; // class recursive_wrapper 113 114 template <typename T> swap(recursive_wrapper<T> & lhs,recursive_wrapper<T> & rhs)115inline void swap(recursive_wrapper<T>& lhs, recursive_wrapper<T>& rhs) noexcept 116 { 117 lhs.swap(rhs); 118 } 119 } // namespace util 120 } // namespace mapbox 121 122 #endif // MAPBOX_UTIL_RECURSIVE_WRAPPER_HPP 123