1 //  Copyright (c) 2020 Andrey Semashev
2 //
3 //  Distributed under the Boost Software License, Version 1.0.
4 //  See accompanying file LICENSE_1_0.txt or copy at
5 //  http://www.boost.org/LICENSE_1_0.txt)
6 
7 #ifndef BOOST_ATOMIC_TESTS_ALIGNED_OBJECT_HPP_INCLUDED_
8 #define BOOST_ATOMIC_TESTS_ALIGNED_OBJECT_HPP_INCLUDED_
9 
10 #include <cstddef>
11 #include <new>
12 #include <boost/config.hpp>
13 #include <boost/cstdint.hpp>
14 
15 //! A wrapper that creates an object that has at least the specified alignment
16 template< typename T, std::size_t Alignment >
17 class aligned_object
18 {
19 private:
20     T* m_p;
21     unsigned char m_storage[Alignment + sizeof(T)];
22 
23 public:
aligned_object()24     aligned_object()
25     {
26         m_p = new (get_aligned_storage()) T;
27     }
28 
aligned_object(T const & value)29     explicit aligned_object(T const& value)
30     {
31         m_p = new (get_aligned_storage()) T(value);
32     }
33 
~aligned_object()34     ~aligned_object() BOOST_NOEXCEPT
35     {
36         m_p->~T();
37     }
38 
get() const39     T& get() const BOOST_NOEXCEPT
40     {
41         return *m_p;
42     }
43 
44     BOOST_DELETED_FUNCTION(aligned_object(aligned_object const&))
45     BOOST_DELETED_FUNCTION(aligned_object& operator= (aligned_object const&))
46 
47 private:
get_aligned_storage()48     unsigned char* get_aligned_storage()
49     {
50 #if defined(BOOST_HAS_INTPTR_T)
51         typedef boost::uintptr_t uintptr_type;
52 #else
53         typedef std::size_t uintptr_type;
54 #endif
55         unsigned char* p = m_storage;
56         uintptr_type misalignment = ((uintptr_type)p) & (Alignment - 1u);
57         if (misalignment > 0)
58             p += Alignment - misalignment;
59         return p;
60     }
61 };
62 
63 #endif // BOOST_ATOMIC_TESTS_ALIGNED_OBJECT_HPP_INCLUDED_
64