| 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) |
| 43 | void const* address() const { return &dummy_; } |
| 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 |
| 52 | T const* ptr_ref() const |
| 53 | { |
| 54 | union { void const* ap_pvoid; T const* as_ptype; } caster = { address() }; |
| 55 | return caster.as_ptype; |
| 56 | } |
| 57 | T * ptr_ref() |
| 58 | { |
| 59 | union { void* ap_pvoid; T* as_ptype; } caster = { address() }; |
| 60 | return caster.as_ptype; |
| 61 | } |
| 62 | #else |
| 63 | T const* ptr_ref() const { return static_cast<T const*>(address()); } |
| 64 | T * ptr_ref() { return static_cast<T *> (address()); } |
| 65 | #endif |
| 66 | |
| 67 | T const& ref() const { return *ptr_ref(); } |
| 68 | T & ref() { return *ptr_ref(); } |
| 69 | |
| 70 | } ; |
| 71 | |
| 72 | } // namespace optional_detail |
| 73 | } // namespace boost |
| 74 | |
| 75 | #endif // header guard |
| 76 | |