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 | |