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 union 29 // This works around GCC warnings about breaking strict aliasing rules when casting storage address to T* 30 #if defined(BOOST_OPTIONAL_DETAIL_USE_ATTRIBUTE_MAY_ALIAS) 31 __attribute__((__may_alias__)) 32 #endif 33 dummy_u 34 { 35 char data[ sizeof(T) ]; 36 BOOST_DEDUCED_TYPENAME type_with_alignment< 37 ::boost::alignment_of<T>::value >::type aligner_; 38 } dummy_ ; 39 40 public: 41 42 #if defined(BOOST_OPTIONAL_DETAIL_USE_ATTRIBUTE_MAY_ALIAS) address() const43 void const* address() const { return &dummy_; } address()44 void * address() { return &dummy_; } 45 #else 46 void const* address() const { return dummy_.data; } 47 void * address() { return dummy_.data; } 48 #endif 49 50 #if defined(BOOST_OPTIONAL_DETAIL_USE_ATTRIBUTE_MAY_ALIAS) 51 // This workaround is supposed to silence GCC warnings about broken strict aliasing rules ptr_ref() const52 T const* ptr_ref() const 53 { 54 union { void const* ap_pvoid; T const* as_ptype; } caster = { address() }; 55 return caster.as_ptype; 56 } ptr_ref()57 T * ptr_ref() 58 { 59 union { void* ap_pvoid; T* as_ptype; } caster = { address() }; 60 return caster.as_ptype; 61 } 62 #else ptr_ref() const63 T const* ptr_ref() const { return static_cast<T const*>(address()); } ptr_ref()64 T * ptr_ref() { return static_cast<T *> (address()); } 65 #endif 66 ref() const67 T const& ref() const { return *ptr_ref(); } ref()68 T & ref() { return *ptr_ref(); } 69 70 } ; 71 72 } // namespace optional_detail 73 } // namespace boost 74 75 #endif // header guard 76