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
17namespace boost {
18
19namespace 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)
24template <class T>
25class 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