1 // Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal. 2 // Copyright (C) 2016 Andrzej Krzemienski. 3 // 4 // Use, modification, and distribution is subject to the Boost Software 5 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 6 // http://www.boost.org/LICENSE_1_0.txt) 7 // 8 // See http://www.boost.org/libs/optional for documentation. 9 // 10 // You are welcome to contact the author at: 11 // fernando_cacciola@hotmail.com 12 // akrzemi1@gmail.com 13 14 #ifndef BOOST_OPTIONAL_OPTIONAL_DETAIL_OPTIONAL_ALIGNED_STORAGE_AJK_12FEB2016_HPP 15 #define BOOST_OPTIONAL_OPTIONAL_DETAIL_OPTIONAL_ALIGNED_STORAGE_AJK_12FEB2016_HPP 16 17 namespace boost { 18 19 namespace optional_detail { 20 // This local class is used instead of that in "aligned_storage.hpp" 21 // because I've found the 'official' class to ICE BCB5.5 22 // when some types are used with optional<> 23 // (due to sizeof() passed down as a non-type template parameter) 24 template <class T> 25 class aligned_storage 26 { 27 // Borland ICEs if unnamed unions are used for this! 28 // BOOST_MAY_ALIAS works around GCC warnings about breaking strict aliasing rules when casting storage address to T* 29 union BOOST_MAY_ALIAS dummy_u 30 { 31 char data[ sizeof(T) ]; 32 BOOST_DEDUCED_TYPENAME type_with_alignment< 33 ::boost::alignment_of<T>::value >::type aligner_; 34 } dummy_ ; 35 36 public: 37 38 #if defined(BOOST_OPTIONAL_DETAIL_USE_ATTRIBUTE_MAY_ALIAS) address() const39 void const* address() const { return &dummy_; } address()40 void * address() { return &dummy_; } 41 #else 42 void const* address() const { return dummy_.data; } 43 void * address() { return dummy_.data; } 44 #endif 45 46 #if defined(BOOST_OPTIONAL_DETAIL_USE_ATTRIBUTE_MAY_ALIAS) 47 // This workaround is supposed to silence GCC warnings about broken strict aliasing rules ptr_ref() const48 T const* ptr_ref() const 49 { 50 union { void const* ap_pvoid; T const* as_ptype; } caster = { address() }; 51 return caster.as_ptype; 52 } ptr_ref()53 T * ptr_ref() 54 { 55 union { void* ap_pvoid; T* as_ptype; } caster = { address() }; 56 return caster.as_ptype; 57 } 58 #else ptr_ref() const59 T const* ptr_ref() const { return static_cast<T const*>(address()); } ptr_ref()60 T * ptr_ref() { return static_cast<T *> (address()); } 61 #endif 62 ref() const63 T const& ref() const { return *ptr_ref(); } ref()64 T & ref() { return *ptr_ref(); } 65 66 } ; 67 68 } // namespace optional_detail 69 } // namespace boost 70 71 #endif // header guard 72