1/* Copyright (C) 2011-2014 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_NOT_IMPLEMENTED_H
9#define LIBSIMDPP_SIMDPP_DETAIL_NOT_IMPLEMENTED_H
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 <type_traits>
17
18namespace simdpp {
19namespace SIMDPP_ARCH_NAMESPACE {
20
21namespace detail {
22
23/** A data type that can be implicitly converted to all types used in the
24 library. Used to silence 'no return value' warnings
25*/
26class dummy_value {
27public:
28 template<unsigned N> operator int8<N>() { return int8<N>(); }
29 template<unsigned N> operator uint8<N>() { return uint8<N>(); }
30 template<unsigned N> operator mask_int8<N>() { return mask_int8<N>(); }
31 template<unsigned N> operator int16<N>() { return int16<N>(); }
32 template<unsigned N> operator uint16<N>() { return uint16<N>(); }
33 template<unsigned N> operator mask_int16<N>() { return mask_int16<N>(); }
34 template<unsigned N> operator int32<N>() { return int32<N>(); }
35 template<unsigned N> operator uint32<N>() { return uint32<N>(); }
36 template<unsigned N> operator mask_int32<N>() { return mask_int32<N>(); }
37 template<unsigned N> operator int64<N>() { return int64<N>(); }
38 template<unsigned N> operator uint64<N>() { return uint64<N>(); }
39 template<unsigned N> operator mask_int64<N>() { return mask_int64<N>(); }
40 template<unsigned N> operator float32<N>() { return float32<N>(); }
41 template<unsigned N> operator mask_float32<N>() { return mask_float32<N>(); }
42 template<unsigned N> operator float64<N>() { return float64<N>(); }
43 template<unsigned N> operator mask_float64<N>() { return mask_float64<N>(); }
44
45 template<unsigned N> operator int8<N,expr_empty>() { return int8<N>(); }
46 template<unsigned N> operator uint8<N,expr_empty>() { return uint8<N>(); }
47 template<unsigned N> operator mask_int8<N,expr_empty>() { return mask_int8<N>(); }
48 template<unsigned N> operator int16<N,expr_empty>() { return int16<N>(); }
49 template<unsigned N> operator uint16<N,expr_empty>() { return uint16<N>(); }
50 template<unsigned N> operator mask_int16<N,expr_empty>() { return mask_int16<N>(); }
51 template<unsigned N> operator int32<N,expr_empty>() { return int32<N>(); }
52 template<unsigned N> operator uint32<N,expr_empty>() { return uint32<N>(); }
53 template<unsigned N> operator mask_int32<N,expr_empty>() { return mask_int32<N>(); }
54 template<unsigned N> operator int64<N,expr_empty>() { return int64<N>(); }
55 template<unsigned N> operator uint64<N,expr_empty>() { return uint64<N>(); }
56 template<unsigned N> operator mask_int64<N,expr_empty>() { return mask_int64<N>(); }
57 template<unsigned N> operator float32<N,expr_empty>() { return float32<N>(); }
58 template<unsigned N> operator mask_float32<N,expr_empty>() { return mask_float32<N>(); }
59 template<unsigned N> operator float64<N,expr_empty>() { return float64<N>(); }
60 template<unsigned N> operator mask_float64<N,expr_empty>() { return mask_float64<N>(); }
61
62 operator int32_t() { return 0; }
63 operator uint32_t() { return 0; }
64 operator int64_t() { return 0; }
65 operator uint64_t() { return 0; }
66 operator float() { return 0; }
67 operator double() { return 0; }
68};
69
70} // namespace detail
71
72/** Causes compile-time error whenever unimplemented functionality is used.
73 The function may only be used in templates which are not instantiated by
74 default.
75*/
76template<class T>
77void libsimdpp_instruction_not_available_template()
78{
79 static_assert(!std::is_same<T, T>::value, "The instruction is not available");
80}
81
82/** Causes linker error whenever unimplemented functionality is used. Compared
83 to libsimdpp_instruction_not_available, this function is not limited to
84 template contexts, but the errors are much harder to track down.
85*/
86void libsimdpp_instruction_not_available0();
87void libsimdpp_instruction_not_available1();
88void libsimdpp_instruction_not_available2();
89void libsimdpp_instruction_not_available3();
90void libsimdpp_instruction_not_available4();
91
92#define SIMDPP_NOT_IMPLEMENTED_TEMPLATE0(T) ( \
93 libsimdpp_instruction_not_available_template<T>(), \
94 ::simdpp::SIMDPP_ARCH_NAMESPACE::detail::dummy_value() \
95 )
96
97#define SIMDPP_NOT_IMPLEMENTED_TEMPLATE1(T,A) ( \
98 (void) A, \
99 libsimdpp_instruction_not_available_template<T>(), \
100 ::simdpp::SIMDPP_ARCH_NAMESPACE::detail::dummy_value() \
101 )
102
103#define SIMDPP_NOT_IMPLEMENTED_TEMPLATE2(T,A,B) ( \
104 (void) A, (void) B, \
105 libsimdpp_instruction_not_available_template<T>(), \
106 ::simdpp::SIMDPP_ARCH_NAMESPACE::detail::dummy_value() \
107 )
108
109#define SIMDPP_NOT_IMPLEMENTED_TEMPLATE3(T,A,B,C) ( \
110 (void) A, (void) B, (void) C, \
111 libsimdpp_instruction_not_available_template<T>(), \
112 ::simdpp::SIMDPP_ARCH_NAMESPACE::detail::dummy_value() \
113 )
114
115#define SIMDPP_NOT_IMPLEMENTED_TEMPLATE4(T,A,B,C,D) ( \
116 (void) A, (void) B, (void) C, (void) D, \
117 libsimdpp_instruction_not_available_template<T>(), \
118 ::simdpp::SIMDPP_ARCH_NAMESPACE::detail::dummy_value() \
119 )
120
121#define SIMDPP_NOT_IMPLEMENTED0() ( \
122 libsimdpp_instruction_not_available0(), \
123 ::simdpp::SIMDPP_ARCH_NAMESPACE::detail::dummy_value() \
124 )
125
126#define SIMDPP_NOT_IMPLEMENTED1(A) ( \
127 (void) A, \
128 libsimdpp_instruction_not_available1(), \
129 ::simdpp::SIMDPP_ARCH_NAMESPACE::detail::dummy_value() \
130 )
131
132#define SIMDPP_NOT_IMPLEMENTED2(A,B) ( \
133 (void) A, (void) B, \
134 libsimdpp_instruction_not_available2(), \
135 ::simdpp::SIMDPP_ARCH_NAMESPACE::detail::dummy_value() \
136 )
137
138#define SIMDPP_NOT_IMPLEMENTED3(A,B,C) ( \
139 (void) A, (void) B, (void) C, \
140 libsimdpp_instruction_not_available3(), \
141 ::simdpp::SIMDPP_ARCH_NAMESPACE::detail::dummy_value() \
142 )
143
144#define SIMDPP_NOT_IMPLEMENTED4(A,B,C,D) ( \
145 (void) A, (void) B, (void) C, (void) D, \
146 libsimdpp_instruction_not_available4(), \
147 ::simdpp::SIMDPP_ARCH_NAMESPACE::detail::dummy_value() \
148 )
149
150} // namespace SIMDPP_ARCH_NAMESPACE
151} // namespace simdpp
152
153#endif
154