Line data Source code
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) 39 0 : void const* address() const { return &dummy_; } 40 0 : 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 48 0 : T const* ptr_ref() const 49 : { 50 0 : union { void const* ap_pvoid; T const* as_ptype; } caster = { address() }; 51 : return caster.as_ptype; 52 : } 53 0 : T * ptr_ref() 54 : { 55 0 : union { void* ap_pvoid; T* as_ptype; } caster = { address() }; 56 : return caster.as_ptype; 57 : } 58 : #else 59 : T const* ptr_ref() const { return static_cast<T const*>(address()); } 60 : T * ptr_ref() { return static_cast<T *> (address()); } 61 : #endif 62 : 63 0 : T const& ref() const { return *ptr_ref(); } 64 0 : T & ref() { return *ptr_ref(); } 65 : 66 : } ; 67 : 68 : } // namespace optional_detail 69 : } // namespace boost 70 : 71 : #endif // header guard