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 | void const* address() const { return &dummy_; } |
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 |
48 | T const* ptr_ref() const |
49 | { |
50 | union { void const* ap_pvoid; T const* as_ptype; } caster = { address() }; |
51 | return caster.as_ptype; |
52 | } |
53 | T * ptr_ref() |
54 | { |
55 | 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 | T const& ref() const { return *ptr_ref(); } |
64 | T & ref() { return *ptr_ref(); } |
65 | |
66 | } ; |
67 | |
68 | } // namespace optional_detail |
69 | } // namespace boost |
70 | |
71 | #endif // header guard |
72 | |