]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 |