Skip to content
Snippets Groups Projects
alignment.hh 2.99 KiB
Newer Older
  • Learn to ignore specific revisions
  • // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    // vi: set et ts=4 sw=2 sts=2:
    // $Id$
    
    #ifndef DUNE_ALIGNMENT_HH
    #define DUNE_ALIGNMENT_HH
    
    Martin Nolte's avatar
    Martin Nolte committed
    #if HAVE_TYPE_TRAITS
    
    #include <type_traits>
    
    Martin Nolte's avatar
    Martin Nolte committed
    #elif HAVE_TR1_TYPE_TRAITS
    
    #include <tr1/type_traits>
    #endif
    
    
    namespace Dune
    {
    
      /** @addtogroup Common
       *
       * @{
       */
      /**
       * @file
       * @brief This file implements a template class to determine alignment
    
       * requirements of types at compile time.
    
    Oliver Sander's avatar
    Oliver Sander committed
         * @brief Helper class to measure alignment requirement.
         * @tparam T The type we want to measure the alignment requirement for.
    
         */
        template<class T>
        struct AlignmentStruct
        {
          char c;
          T t;
          void hack();
        };
    
        /**
    
    Oliver Sander's avatar
    Oliver Sander committed
         * @brief Helper class to measure alignment requirement.
         * @tparam T The type we want to measure the alignment requirement for.
    
         */
        template<class T, std::size_t N>
        struct AlignmentHelper
        {
          enum { N2 = sizeof(AlignmentStruct<T>) - sizeof(T) - N };
          char padding1[N];
          T t;
          char padding2[N2];
        };
    
    #define ALIGNMENT_MODULO(a, b)   (a % b == 0 ? \
                                      static_cast<std::size_t>(b) : \
                                      static_cast<std::size_t>(a % b))
    
    #define ALIGNMENT_MIN(a, b)      (static_cast<std::size_t>(a) <   \
    
                                      static_cast<std::size_t>(b) ? \
                                      static_cast<std::size_t>(a) : \
                                      static_cast<std::size_t>(b))
    
        /**  @brief does the actual calculations. */
        template <class T, std::size_t N>
        struct AlignmentTester
    
          typedef AlignmentStruct<T>        s;
          typedef AlignmentHelper<T, N>     h;
          typedef AlignmentTester<T, N - 1> next;
          enum
          {
            a1       = ALIGNMENT_MODULO(N        , sizeof(T)),
            a2       = ALIGNMENT_MODULO(h::N2    , sizeof(T)),
            a3       = ALIGNMENT_MODULO(sizeof(h), sizeof(T)),
            a        = sizeof(h) == sizeof(s) ? ALIGNMENT_MIN(a1, a2) : a3,
            result   = ALIGNMENT_MIN(a, next::result)
          };
    
        /**  @brief does the actual calculations. */
        template <class T>
        struct AlignmentTester<T, 0>
    
          enum
          {
            result = ALIGNMENT_MODULO(sizeof(AlignmentStruct<T>), sizeof(T))
          };
    
    Oliver Sander's avatar
    Oliver Sander committed
      } //end anonymous namespace
    
       * @brief Calculates the alignment requirement of a type.
       *
    
       * @see http://en.wikipedia.org/wiki/Data_structure_alignment
       *
    
       * This will be a safe value and not an optimal one.
       * If TR1 is available it falls back to std::alignment_of.
    
       */
      template <class T>
      struct AlignmentOf
      {
    
    Oliver Sander's avatar
    Oliver Sander committed
          /** @brief The alignment requirement. */
    
    #ifdef HAVE_TYPE_TRAITS
          value = std::alignment_of<T>::value
    #elif HAVE_TR1_TYPETRAITS
          value = std::tr1::alignment_of<T>::value
    #else
          value = AlignmentTester<T, sizeof(AlignmentStruct<T>) - sizeof(T) -1>::result
    #endif