lean cpp library
A lean C++ library providing efficient utility classes for high-performance C++ applications.
|
00001 /*****************************************************/ 00002 /* lean PImpl (c) Tobias Zirr 2011 */ 00003 /*****************************************************/ 00004 00005 #ifndef LEAN_PIMPL_FORWARD_VAL 00006 #define LEAN_PIMPL_FORWARD_VAL 00007 00008 #include "../cpp0x.h" 00009 00010 namespace lean 00011 { 00012 namespace pimpl 00013 { 00014 00016 template <class Value, size_t Size> 00017 class forward_val 00018 { 00019 private: 00020 char m_value[Size]; 00021 00023 LEAN_INLINE static void assert_size() 00024 { 00025 LEAN_STATIC_ASSERT_MSG_ALT(sizeof(Value) == Size, 00026 "specified size does not match value size", 00027 specified_size_does_not_match_value_size); 00028 } 00029 00030 public: 00032 typedef Value value_type; 00033 00035 forward_val() 00036 { 00037 assert_size(); 00038 new(static_cast<void*>(m_value)) Value(); 00039 } 00041 forward_val(const value_type &value) 00042 { 00043 assert_size(); 00044 new(static_cast<void*>(m_value)) Value(value); 00045 } 00047 forward_val(const forward_val &right) 00048 { 00049 assert_size(); 00050 new(static_cast<void*>(m_value)) Value(right.get()); 00051 } 00052 #ifndef LEAN0X_NO_RVALUE_REFERENCES 00053 00054 forward_val(value_type &&value) 00055 { 00056 assert_size(); 00057 new(static_cast<void*>(m_value)) Value(std::move(value)); 00058 } 00060 forward_val(forward_val &&right) 00061 { 00062 assert_size(); 00063 new(static_cast<void*>(m_value)) Value(std::move(right.get())); 00064 } 00065 #endif 00066 00067 ~forward_val() 00068 { 00069 get().~Value(); 00070 } 00071 00073 forward_val& operator =(const value_type &value) 00074 { 00075 get() = value; 00076 return *this; 00077 } 00079 forward_val& operator =(const forward_val &right) 00080 { 00081 get() = right.get(); 00082 return *this; 00083 } 00084 #ifndef LEAN0X_NO_RVALUE_REFERENCES 00085 00086 forward_val& operator =(value_type &&value) 00087 { 00088 get() = std::move(value); 00089 return *this; 00090 } 00092 forward_val& operator =(forward_val &&right) 00093 { 00094 get() = std::move(right.get()); 00095 return *this; 00096 } 00097 #endif 00098 00100 LEAN_INLINE value_type* getptr(void) { assert_size(); return reinterpret_cast<Value*>(m_value); } 00102 LEAN_INLINE const value_type* getptr(void) const { assert_size(); return reinterpret_cast<const Value*>(m_value); } 00104 LEAN_INLINE value_type& get(void) { return *getptr(); } 00106 LEAN_INLINE const value_type& get(void) const { return *getptr(); } 00107 00109 LEAN_INLINE value_type& operator *() { return get(); } 00111 LEAN_INLINE const value_type& operator *() const { return get(); } 00113 LEAN_INLINE value_type* operator ->() { return getptr(); } 00115 LEAN_INLINE const value_type* operator ->() const { return getptr(); } 00116 00118 LEAN_INLINE operator value_type&() { return get(); } 00120 LEAN_INLINE operator const value_type&() const { return get(); } 00121 }; 00122 00123 } // namespace 00124 00125 using pimpl::forward_val; 00126 00127 } // namespace 00128 00129 #endif