lean cpp library
A lean C++ library providing efficient utility classes for high-performance C++ applications.
forward_val.h
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