File: aligned_type.h

package info (click to toggle)
libcds 2.3.3-6
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 15,632 kB
  • sloc: cpp: 135,002; ansic: 7,234; perl: 243; sh: 237; makefile: 6
file content (83 lines) | stat: -rw-r--r-- 2,996 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// Copyright (c) 2006-2018 Maxim Khizhinsky
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)

#ifndef CDSLIB_DETAILS_ALIGNED_TYPE_H
#define CDSLIB_DETAILS_ALIGNED_TYPE_H

#include <cds/details/defs.h>

namespace cds { namespace details {

    /// Aligned type
    /**
        This meta-algorithm solves compiler problem when you need to declare a type \p T with alignment
        equal to another type alignment. For example, the following declaration produces an error in Microsoft Visual Studio 2008 compiler:
        \code
            typedef double  my_double;
            typedef __declspec(align( __alignof(my_double))) int   aligned_int;
        \endcode
        In MS VS, the __declspec(align(N)) construction requires that N must be a integer constant (1, 2, 4 and so on)
        but not an integer constant expression.

        The result of this meta-algo is a type \p aligned_type<T,Alignment>::type that is \p T aligned by \p Alignment.
        For example, with \p aligned_type the prevoius example will not generate an error:
        \code
            typedef double  my_double;
            typedef typename cds::details::aligned_type<int, __alignof(my_double)>::type   aligned_int;
        \endcode
        and result of this declaration is equivalent to
        \code
            typedef __declspec(align(8)) int   aligned_int;
        \endcode

        The \p Alignment template parameter must be a constant expression and its result must be power of two.
        The maximum of its value is 1024.

        See also \ref align_as
    */
    template <typename T, size_t Alignment>
    struct aligned_type
#ifdef CDS_DOXYGEN_INVOKED
        {}
#endif
;

    //@cond none
#   define CDS_ALIGNED_TYPE_impl(nAlign) template <typename T> struct aligned_type<T,nAlign> { typedef CDS_TYPE_ALIGNMENT(nAlign) T type; }
    CDS_ALIGNED_TYPE_impl(1);
    CDS_ALIGNED_TYPE_impl(2);
    CDS_ALIGNED_TYPE_impl(4);
    CDS_ALIGNED_TYPE_impl(8);
    CDS_ALIGNED_TYPE_impl(16);
    CDS_ALIGNED_TYPE_impl(32);
    CDS_ALIGNED_TYPE_impl(64);
    CDS_ALIGNED_TYPE_impl(128);
    CDS_ALIGNED_TYPE_impl(256);
    CDS_ALIGNED_TYPE_impl(512);
    CDS_ALIGNED_TYPE_impl(1024);
#   undef CDS_ALIGNED_TYPE_impl
    //@endcond

    /** Alignment by example

        This meta-algo is similar to \ref aligned_type <T, alignof(AlignAs)>.

        For example, the following code
        \code
        typedef typename cds::details::align_as<int, double>::type   aligned_int;
        \endcode
        declares type \p aligned_int which is \p int aligned like \p double.

        See also: \ref aligned_type
    */
    template <typename T, typename AlignAs>
    struct align_as {
        /// Result of meta-algo: type \p T aligned like type \p AlignAs
        typedef typename aligned_type<T, alignof(AlignAs)>::type type;
    };

}}  // namespace cds::details

#endif // #ifndef CDSLIB_DETAILS_ALIGNED_TYPE_H