1. 程式人生 > 其它 >JFrame(用C++11特性重構系列——optional的實現)

JFrame(用C++11特性重構系列——optional的實現)

  1 #pragma once
  2 #include <type_traits>
  3 #include <utility>
  4 #include <stdexcept>
  5 
  6 template<typename T>
  7 class Optional
  8 {
  9     using data_t = typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type;
 10 public:
 11     Optional() : has_init_(false
) {} 12 13 Optional(const T& v) 14 { 15 create(v); 16 } 17 18 Optional(T&& v) : has_init_(false) 19 { 20 create(std::move(v)); 21 } 22 23 ~Optional() 24 { 25 destroy(); 26 } 27 28 Optional(const Optional& other) : has_init_(false
) 29 { 30 if (other.isInit()) 31 assign(other); 32 } 33 34 Optional(Optional&& other) : has_init_(false) 35 { 36 if (other.isInit()) 37 { 38 assign(std::move(other)); 39 other.destroy(); 40 } 41 }
42 43 Optional& operator=(Optional &&other) 44 { 45 assign(std::move(other)); 46 return *this; 47 } 48 49 Optional& operator=(const Optional &other) 50 { 51 assign(other); 52 return *this; 53 } 54 55 template<class... Args> 56 void emplace(Args&&... args) 57 { 58 destroy(); 59 create(std::forward<Args>(args)...); 60 } 61 62 bool isInit() const { return has_init_; } 63 64 explicit operator bool() const 65 { 66 return isInit(); 67 } 68 69 T& operator*() 70 { 71 if(isInit()) 72 { 73 return *((T*) (&data_)); 74 } 75 76 throw std::logic_error{"try to get data in a Optional which is not initialized"}; 77 } 78 79 const T& operator*() const 80 { 81 if(isInit()) 82 { 83 return *((T*) (&data_)); 84 } 85 86 throw std::logic_error{"try to get data in a Optional which is not initialized"}; 87 } 88 89 T* operator->() 90 { 91 return &operator*(); 92 } 93 94 const T* operator->() const 95 { 96 return &operator*(); 97 } 98 99 bool operator==(const Optional<T>& rhs) const 100 { 101 return (!bool(*this)) != (!rhs) ? false : (!bool(*this) ? true : (*(*this)) == (*rhs)); 102 } 103 104 bool operator<(const Optional<T>& rhs) const 105 { 106 return !rhs ? false : (!bool(*this) ? true : (*(*this) < (*rhs))); 107 } 108 109 bool operator!=(const Optional<T>& rhs) 110 { 111 return !(*this == (rhs)); 112 } 113 private: 114 template<class... Args> 115 void create(Args&&... args) 116 { 117 new (&data_) T(std::forward<Args> 118 119 (args)...); 120 has_init_ = true; 121 } 122 123 void destroy() 124 { 125 if (has_init_) 126 { 127 has_init_ = false; 128 ((T*) (&data_))->~T(); 129 } 130 } 131 132 void assign(const Optional& other) 133 { 134 if (other.isInit()) 135 { 136 copy(other.data_); 137 has_init_ = true; 138 } 139 else 140 { 141 destroy(); 142 } 143 } 144 145 void assign(Optional&& other) 146 { 147 if (other.isInit()) 148 { 149 move(std::move(other.data_)); 150 has_init_ = true; 151 other.destroy(); 152 } 153 else 154 { 155 destroy(); 156 } 157 } 158 159 void move(data_t&& val) 160 { 161 destroy(); 162 new (&data_) T(std::move(*((T*)(&val)))); 163 } 164 165 void copy(const data_t& val) 166 { 167 destroy(); 168 new (&data_) T(*((T*) (&val))); 169 } 170 171 private: 172 bool has_init_; 173 data_t data_; 174 };

使用到的 C++11 技術:

  • 記憶體對齊
  • 可變模板引數
  • 右值&完美轉發