1/* Copyright (C) 2013-2017 Povilas Kanapickas <povilas@radix.lt>
2
3 Distributed under the Boost Software License, Version 1.0.
4 (See accompanying file LICENSE_1_0.txt or copy at
5 http://www.boost.org/LICENSE_1_0.txt)
6*/
7
8#ifndef LIBSIMDPP_SIMDPP_DETAIL_INSN_DETAIL_CAST_INL
9#define LIBSIMDPP_SIMDPP_DETAIL_INSN_DETAIL_CAST_INL
10
11#ifndef LIBSIMDPP_SIMD_H
12 #error "This file must be included through simd.h"
13#endif
14
15#include <simdpp/types.h>
16#include <simdpp/detail/cast.h>
17#include <simdpp/detail/cast_bitwise.h>
18#include <simdpp/core/to_mask.h>
19
20namespace simdpp {
21namespace SIMDPP_ARCH_NAMESPACE {
22namespace detail {
23
24template<class T> struct base_mask_vector_type { using type = T; };
25template<unsigned N> struct base_mask_vector_type<mask_int8<N>> { using type = uint8<N>; };
26template<unsigned N> struct base_mask_vector_type<mask_int16<N>> { using type = uint16<N>; };
27template<unsigned N> struct base_mask_vector_type<mask_int32<N>> { using type = uint32<N>; };
28template<unsigned N> struct base_mask_vector_type<mask_int64<N>> { using type = uint64<N>; };
29template<unsigned N> struct base_mask_vector_type<mask_float32<N>> { using type = float32<N>; };
30template<unsigned N> struct base_mask_vector_type<mask_float64<N>> { using type = float64<N>; };
31
32template<class T, class R> SIMDPP_INL
33void cast_bitwise_unmask(const T& t, R& r)
34{
35 using TT = typename base_mask_vector_type<T>::type;
36 TT tt = t.unmask();
37 cast_bitwise_vector(tt, r);
38}
39
40template<class T, class R> SIMDPP_INL
41void cast_bitwise_remask(const T& t, R& r)
42{
43 using BaseMaskVector = typename base_mask_vector_type<R>::type;
44 BaseMaskVector rr;
45 cast_bitwise_vector(t.unmask(), rr);
46 r = to_mask(rr);
47}
48
49template<>
50struct cast_wrapper<CAST_TYPE_OTHER> {
51 template<class T, class R> SIMDPP_INL
52 static void run(const T& t, R& r)
53 {
54 cast_bitwise(t, r);
55 }
56};
57
58template<>
59struct cast_wrapper<CAST_TYPE_MASK_TO_MASK_BITWISE> {
60 template<class T, class R> SIMDPP_INL
61 static void run(const T& t, R& r)
62 {
63 static_assert(R::size_tag == T::size_tag,
64 "Conversions between masks with different element size is"
65 " not allowed");
66 cast_bitwise_vector(t.eval(), r);
67 }
68};
69
70template<>
71struct cast_wrapper<CAST_TYPE_MASK_TO_MASK_UNMASK> {
72 template<class R, class T> SIMDPP_INL
73 static void run(const T& t, R& r)
74 {
75 static_assert(R::size_tag == T::size_tag,
76 "Conversions between masks with different element size is"
77 " not allowed");
78 cast_bitwise_unmask(t.eval(), r);
79 }
80};
81
82template<>
83struct cast_wrapper<CAST_TYPE_MASK_TO_MASK_REMASK> {
84 template<class R, class T> SIMDPP_INL
85 static void run(const T& t, R& r)
86 {
87 static_assert(R::size_tag == T::size_tag,
88 "Conversions between masks with different element size is"
89 " not allowed");
90 cast_bitwise_remask(t.eval(), r);
91 }
92};
93
94template<>
95struct cast_wrapper<CAST_TYPE_VECTOR_TO_MASK> {
96 template<class R, class T> SIMDPP_INL
97 static void run(const T& t, R& r)
98 {
99 (void) t; (void) r;
100 static_assert(!std::is_same<T,T>::value, // fake dependency
101 "Conversion from non-mask type to a mask type is not allowed");
102 }
103};
104
105template<>
106struct cast_wrapper<CAST_TYPE_MASK_TO_VECTOR> {
107 template<class R, class T> SIMDPP_INL
108 static void run(const T& t, R& r)
109 {
110 cast_bitwise_unmask(t.eval(), r);
111 }
112};
113
114template<>
115struct cast_wrapper<CAST_TYPE_VECTOR_TO_VECTOR> {
116 template<class R, class T> SIMDPP_INL
117 static void run(const T& t, R& r)
118 {
119 cast_bitwise_vector(t.eval(), r);
120 }
121};
122
123} // namespace detail
124} // namespace SIMDPP_ARCH_NAMESPACE
125} // namespace simdpp
126
127#endif
128
129