Home | History | Annotate | Download | only in boost
      1 //-----------------------------------------------------------------------------
      2 // boost aligned_storage.hpp header file
      3 // See http://www.boost.org for updates, documentation, and revision history.
      4 //-----------------------------------------------------------------------------
      5 //
      6 // Copyright (c) 2002-2003
      7 // Eric Friedman, Itay Maman
      8 //
      9 // Distributed under the Boost Software License, Version 1.0. (See
     10 // accompanying file LICENSE_1_0.txt or copy at
     11 // http://www.boost.org/LICENSE_1_0.txt)
     12 
     13 #ifndef BOOST_ALIGNED_STORAGE_HPP
     14 #define BOOST_ALIGNED_STORAGE_HPP
     15 
     16 #include <cstddef> // for std::size_t
     17 
     18 #include "boost/config.hpp"
     19 #include "boost/detail/workaround.hpp"
     20 #include "boost/type_traits/alignment_of.hpp"
     21 #include "boost/type_traits/type_with_alignment.hpp"
     22 #include "boost/type_traits/is_pod.hpp"
     23 
     24 #include "boost/mpl/eval_if.hpp"
     25 #include "boost/mpl/identity.hpp"
     26 
     27 #include "boost/type_traits/detail/bool_trait_def.hpp"
     28 
     29 namespace boost {
     30 
     31 namespace detail { namespace aligned_storage {
     32 
     33 BOOST_STATIC_CONSTANT(
     34       std::size_t
     35     , alignment_of_max_align = ::boost::alignment_of<max_align>::value
     36     );
     37 
     38 //
     39 // To be TR1 conforming this must be a POD type:
     40 //
     41 template <
     42       std::size_t size_
     43     , std::size_t alignment_
     44 >
     45 struct aligned_storage_imp
     46 {
     47     union data_t
     48     {
     49         char buf[size_];
     50 
     51         typename mpl::eval_if_c<
     52               alignment_ == std::size_t(-1)
     53             , mpl::identity<detail::max_align>
     54             , type_with_alignment<alignment_>
     55             >::type align_;
     56     } data_;
     57     void* address() const { return const_cast<aligned_storage_imp*>(this); }
     58 };
     59 
     60 template< std::size_t alignment_ >
     61 struct aligned_storage_imp<0u,alignment_>
     62 {
     63     /* intentionally empty */
     64     void* address() const { return 0; }
     65 };
     66 
     67 }} // namespace detail::aligned_storage
     68 
     69 template <
     70       std::size_t size_
     71     , std::size_t alignment_ = std::size_t(-1)
     72 >
     73 class aligned_storage :
     74 #ifndef __BORLANDC__
     75    private
     76 #else
     77    public
     78 #endif
     79    detail::aligned_storage::aligned_storage_imp<size_, alignment_>
     80 {
     81 
     82 public: // constants
     83 
     84     typedef detail::aligned_storage::aligned_storage_imp<size_, alignment_> type;
     85 
     86     BOOST_STATIC_CONSTANT(
     87           std::size_t
     88         , size = size_
     89         );
     90     BOOST_STATIC_CONSTANT(
     91           std::size_t
     92         , alignment = (
     93               alignment_ == std::size_t(-1)
     94             ? ::boost::detail::aligned_storage::alignment_of_max_align
     95             : alignment_
     96             )
     97         );
     98 
     99 #if defined(__GNUC__) &&\
    100     (__GNUC__ >  3) ||\
    101     (__GNUC__ == 3 && (__GNUC_MINOR__ >  2 ||\
    102                       (__GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL__ >=3)))
    103 
    104 private: // noncopyable
    105 
    106     aligned_storage(const aligned_storage&);
    107     aligned_storage& operator=(const aligned_storage&);
    108 
    109 #else // gcc less than 3.2.3
    110 
    111 public: // _should_ be noncopyable, but GCC compiler emits error
    112 
    113     aligned_storage(const aligned_storage&);
    114     aligned_storage& operator=(const aligned_storage&);
    115 
    116 #endif // gcc < 3.2.3 workaround
    117 
    118 public: // structors
    119 
    120     aligned_storage()
    121     {
    122     }
    123 
    124     ~aligned_storage()
    125     {
    126     }
    127 
    128 public: // accessors
    129 
    130     void* address()
    131     {
    132         return static_cast<type*>(this)->address();
    133     }
    134 
    135 #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
    136 
    137     const void* address() const
    138     {
    139         return static_cast<const type*>(this)->address();
    140     }
    141 
    142 #else // MSVC6
    143 
    144     const void* address() const;
    145 
    146 #endif // MSVC6 workaround
    147 
    148 };
    149 
    150 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
    151 
    152 // MSVC6 seems not to like inline functions with const void* returns, so we
    153 // declare the following here:
    154 
    155 template <std::size_t S, std::size_t A>
    156 const void* aligned_storage<S,A>::address() const
    157 {
    158     return const_cast< aligned_storage<S,A>* >(this)->address();
    159 }
    160 
    161 #endif // MSVC6 workaround
    162 
    163 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
    164 //
    165 // Make sure that is_pod recognises aligned_storage<>::type
    166 // as a POD (Note that aligned_storage<> itself is not a POD):
    167 //
    168 template <std::size_t size_, std::size_t alignment_>
    169 struct is_pod<boost::detail::aligned_storage::aligned_storage_imp<size_,alignment_> >
    170    BOOST_TT_AUX_BOOL_C_BASE(true)
    171 {
    172     BOOST_TT_AUX_BOOL_TRAIT_VALUE_DECL(true)
    173 };
    174 #endif
    175 
    176 
    177 } // namespace boost
    178 
    179 #include "boost/type_traits/detail/bool_trait_undef.hpp"
    180 
    181 #endif // BOOST_ALIGNED_STORAGE_HPP
    182