liuxiaolong
2021-07-20 58d904a328c0d849769b483e901a0be9426b8209
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
//Copyright (c) 2018 agate-pris
 
//Distributed under the Boost Software License, Version 1.0. (See accompanying
//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
#ifndef BOOST_QVM_DETAIL_VEC_REGISTER_IMPL_HPP
#define BOOST_QVM_DETAIL_VEC_REGISTER_IMPL_HPP
 
#include <boost/qvm/assert.hpp>
#include <boost/qvm/inline.hpp>
#include <boost/qvm/static_assert.hpp>
#include <boost/qvm/vec_traits.hpp>
 
namespace boost { namespace qvm { namespace qvm_detail {
 
template<class VecType, class ScalarType, int Dim>
struct vec_register_common
{
    typedef VecType vec_type;
    typedef ScalarType scalar_type;
    static int const dim = Dim;
};
 
template<class VecType, class ScalarType, int Dim>
struct vec_register_read
{
    template<int I> static ScalarType read_element(VecType const& v);
 
    template<int I, int N> struct read_element_idx_detail
    {
        static BOOST_QVM_INLINE_CRITICAL ScalarType impl(int const i, VecType const& v)
        {
            return I == i
                ? read_element<I>(v)
                : read_element_idx_detail<I + 1, N>::impl(i, v);
        }
    };
 
    template<int N> struct read_element_idx_detail<N, N>
    {
        static BOOST_QVM_INLINE_TRIVIAL ScalarType impl(int, VecType const& v)
        {
            BOOST_QVM_ASSERT(0);
            return read_element<0>(v);
        }
    };
 
    static BOOST_QVM_INLINE_CRITICAL ScalarType read_element_idx(int const i, VecType const& v)
    {
        return read_element_idx_detail<0, Dim>::impl(i, v);
    }
};
 
template<class VecType, class ScalarType, int Dim>
struct vec_register_write
{
    template<int I> static ScalarType& write_element(VecType& v);
 
    template<int I, int N> struct write_element_idx_detail
    {
        static BOOST_QVM_INLINE_CRITICAL ScalarType& impl(int const i, VecType& v)
        {
            return I == i
                ? write_element<I>(v)
                : write_element_idx_detail<I + 1, N>::impl(i, v);
        }
    };
 
    template<int N> struct write_element_idx_detail<N, N>
    {
        static BOOST_QVM_INLINE_TRIVIAL ScalarType& impl(int, VecType& v)
        {
            BOOST_QVM_ASSERT(0);
            return write_element<0>(v);
        }
    };
 
    static BOOST_QVM_INLINE_CRITICAL ScalarType& write_element_idx(int const i, VecType& v)
    {
        return write_element_idx_detail<0, Dim>::impl(i, v);
    }
};
 
}}}
 
#define BOOST_QVM_DETAIL_SPECIALIZE_QVM_DETAIL_VEC_REGISTER_READ(VecType, ScalarType, Dim, I, Read) \
namespace boost { namespace qvm {namespace qvm_detail{ \
template<> \
template<> \
BOOST_QVM_INLINE_CRITICAL \
ScalarType vec_register_read<VecType, ScalarType, Dim>::read_element<I>(VecType const& v) \
{ \
    BOOST_QVM_STATIC_ASSERT(I>=0); \
    BOOST_QVM_STATIC_ASSERT(I<Dim); \
    return v. Read; \
} \
}}}
 
#define BOOST_QVM_DETAIL_SPECIALIZE_QVM_DETAIL_VEC_REGISTER_WRITE(VecType, ScalarType, Dim, I, Write) \
namespace boost { namespace qvm {namespace qvm_detail{ \
template<> \
template<> \
BOOST_QVM_INLINE_CRITICAL \
ScalarType& vec_register_write<VecType, ScalarType, Dim>::write_element<I>(VecType& v) \
{ \
    BOOST_QVM_STATIC_ASSERT(I>=0); \
    BOOST_QVM_STATIC_ASSERT(I<Dim); \
    return v. Write; \
}; \
}}}
 
#define BOOST_QVM_DETAIL_SPECIALIZE_QVM_DETAIL_VEC_REGISTER_READ_WRITE(VecType, ScalarType, Dim, I, Read, Write)\
BOOST_QVM_DETAIL_SPECIALIZE_QVM_DETAIL_VEC_REGISTER_READ(VecType, ScalarType, Dim, I, Read) \
BOOST_QVM_DETAIL_SPECIALIZE_QVM_DETAIL_VEC_REGISTER_WRITE(VecType, ScalarType, Dim, I, Write)
 
#define BOOST_QVM_DETAIL_REGISTER_VEC_SPECIALIZE_VEC_TRAITS_READ(VecType, ScalarType, Dim) \
namespace boost { namespace qvm { \
template<> \
struct vec_traits<VecType> \
: qvm_detail::vec_register_common<VecType, ScalarType, Dim> \
, qvm_detail::vec_register_read<VecType, ScalarType, Dim> \
{ \
}; \
}}
 
#define BOOST_QVM_DETAIL_REGISTER_VEC_SPECIALIZE_VEC_TRAITS_READ_WRITE(VecType, ScalarType, Dim)\
namespace boost { namespace qvm { \
template<> \
struct vec_traits<VecType> \
: qvm_detail::vec_register_common<VecType, ScalarType, Dim> \
, qvm_detail::vec_register_read<VecType, ScalarType, Dim> \
, qvm_detail::vec_register_write<VecType, ScalarType, Dim> \
{ \
}; \
}}
 
#endif