1
2// (C) Copyright John Maddock 2000.
3// Use, modification and distribution are subject to the Boost Software License,
4// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
5// http://www.boost.org/LICENSE_1_0.txt).
6//
7// See http://www.boost.org/libs/type_traits for most recent version including documentation.
8
9#ifndef BOOST_TT_ALIGNMENT_OF_HPP_INCLUDED
10#define BOOST_TT_ALIGNMENT_OF_HPP_INCLUDED
11
12#include <boost/config.hpp>
13#include <cstddef>
14
15#include <boost/type_traits/intrinsics.hpp>
16#include <boost/type_traits/integral_constant.hpp>
17
18#ifdef BOOST_MSVC
19# pragma warning(push)
20# pragma warning(disable: 4121 4512) // alignment is sensitive to packing
21#endif
22#if defined(__BORLANDC__) && (__BORLANDC__ < 0x600)
23#pragma option push -Vx- -Ve-
24#endif
25
26namespace boost {
27
28template <typename T> struct alignment_of;
29
30// get the alignment of some arbitrary type:
31namespace detail {
32
33#ifdef BOOST_MSVC
34#pragma warning(push)
35#pragma warning(disable:4324) // structure was padded due to __declspec(align())
36#endif
37template <typename T>
38struct alignment_of_hack
39{
40 char c;
41 T t;
42 alignment_of_hack();
43};
44#ifdef BOOST_MSVC
45#pragma warning(pop)
46#endif
47
48template <unsigned A, unsigned S>
49struct alignment_logic
50{
51 BOOST_STATIC_CONSTANT(std::size_t, value = A < S ? A : S);
52};
53
54
55template< typename T >
56struct alignment_of_impl
57{
58#if defined(BOOST_MSVC) && (BOOST_MSVC >= 1400)
59 //
60 // With MSVC both the native __alignof operator
61 // and our own logic gets things wrong from time to time :-(
62 // Using a combination of the two seems to make the most of a bad job:
63 //
64 BOOST_STATIC_CONSTANT(std::size_t, value =
65 (::boost::detail::alignment_logic<
66 sizeof(::boost::detail::alignment_of_hack<T>) - sizeof(T),
67 __alignof(T)
68 >::value));
69#elif !defined(BOOST_ALIGNMENT_OF)
70 BOOST_STATIC_CONSTANT(std::size_t, value =
71 (::boost::detail::alignment_logic<
72 sizeof(::boost::detail::alignment_of_hack<T>) - sizeof(T),
73 sizeof(T)
74 >::value));
75#else
76 //
77 // We put this here, rather than in the definition of
78 // alignment_of below, because MSVC's __alignof doesn't
79 // always work in that context for some unexplained reason.
80 // (See type_with_alignment tests for test cases).
81 //
82 BOOST_STATIC_CONSTANT(std::size_t, value = BOOST_ALIGNMENT_OF(T));
83#endif
84};
85
86} // namespace detail
87
88template <class T> struct alignment_of : public integral_constant<std::size_t, ::boost::detail::alignment_of_impl<T>::value>{};
89
90// references have to be treated specially, assume
91// that a reference is just a special pointer:
92template <typename T> struct alignment_of<T&> : public alignment_of<T*>{};
93
94#ifdef __BORLANDC__
95// long double gives an incorrect value of 10 (!)
96// unless we do this...
97struct long_double_wrapper{ long double ld; };
98template<> struct alignment_of<long double> : public alignment_of<long_double_wrapper>{};
99#endif
100
101// void has to be treated specially:
102template<> struct alignment_of<void> : integral_constant<std::size_t, 0>{};
103#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
104template<> struct alignment_of<void const> : integral_constant<std::size_t, 0>{};
105template<> struct alignment_of<void const volatile> : integral_constant<std::size_t, 0>{};
106template<> struct alignment_of<void volatile> : integral_constant<std::size_t, 0>{};
107#endif
108
109} // namespace boost
110
111#if defined(__BORLANDC__) && (__BORLANDC__ < 0x600)
112#pragma option pop
113#endif
114#ifdef BOOST_MSVC
115# pragma warning(pop)
116#endif
117
118#endif // BOOST_TT_ALIGNMENT_OF_HPP_INCLUDED
119
120