32#ifndef _r123array_dot_h__
33#define _r123array_dot_h__
37#if !defined(__cplusplus) || defined(__METAL_MACOS__)
38#define CXXMETHODS(_N, W, T)
39#define CXXOVERLOADS(_N, W, T)
40#define CXXMETHODS_REQUIRING_STL
76 for(
size_t i = 0; i < (3 +
sizeof(value_type)) / 4; ++i)
77 v |= ((value_type)(*p32++)) << (32 * i);
87#define CXXMETHODS_REQUIRING_STL
89#define CXXMETHODS_REQUIRING_STL \
91 typedef std::reverse_iterator<iterator> reverse_iterator; \
92 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; \
93 R123_CUDA_DEVICE reverse_iterator rbegin() { return reverse_iterator(end()); } \
94 R123_CUDA_DEVICE const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } \
95 R123_CUDA_DEVICE reverse_iterator rend() { return reverse_iterator(begin()); } \
96 R123_CUDA_DEVICE const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } \
97 R123_CUDA_DEVICE const_reverse_iterator crbegin() const { return const_reverse_iterator(cend()); } \
98 R123_CUDA_DEVICE const_reverse_iterator crend() const { return const_reverse_iterator(cbegin()); }
102#define CXXMETHODS(_N, W, T) \
103 typedef T value_type; \
104 typedef T* iterator; \
105 typedef const T* const_iterator; \
106 typedef value_type& reference; \
107 typedef value_type const& const_reference; \
108 typedef size_t size_type; \
109 typedef ptrdiff_t difference_type; \
110 typedef T* pointer; \
111 typedef const T* const_pointer; \
113 enum { static_size = _N }; \
114 R123_CUDA_DEVICE reference operator[](size_type i) { return v[i]; } \
115 R123_CUDA_DEVICE const_reference operator[](size_type i) const { return v[i]; } \
116 R123_CUDA_DEVICE reference at(size_type i) { \
118 R123_THROW(std::out_of_range("array index out of range")); \
121 R123_CUDA_DEVICE const_reference at(size_type i) const { \
123 R123_THROW(std::out_of_range("array index out of range")); \
126 R123_CUDA_DEVICE size_type size() const { return _N; } \
127 R123_CUDA_DEVICE size_type max_size() const { return _N; } \
128 R123_CUDA_DEVICE bool empty() const { return _N == 0; }; \
129 R123_CUDA_DEVICE iterator begin() { return &v[0]; } \
130 R123_CUDA_DEVICE iterator end() { return &v[_N]; } \
131 R123_CUDA_DEVICE const_iterator begin() const { return &v[0]; } \
132 R123_CUDA_DEVICE const_iterator end() const { return &v[_N]; } \
133 R123_CUDA_DEVICE const_iterator cbegin() const { return &v[0]; } \
134 R123_CUDA_DEVICE const_iterator cend() const { return &v[_N]; } \
135 R123_CUDA_DEVICE pointer data() { return &v[0]; } \
136 R123_CUDA_DEVICE const_pointer data() const { return &v[0]; } \
137 R123_CUDA_DEVICE reference front() { return v[0]; } \
138 R123_CUDA_DEVICE const_reference front() const { return v[0]; } \
139 R123_CUDA_DEVICE reference back() { return v[_N - 1]; } \
140 R123_CUDA_DEVICE const_reference back() const { return v[_N - 1]; } \
141 R123_CUDA_DEVICE bool operator==(const r123array##_N##x##W& rhs) const { \
143 for(size_t i = 0; i < _N; ++i) \
144 if(v[i] != rhs.v[i]) \
148 R123_CUDA_DEVICE bool operator!=(const r123array##_N##x##W& rhs) const { return !(*this == rhs); } \
150 R123_CUDA_DEVICE void fill(value_type const& val) { \
151 for(size_t i = 0; i < _N; ++i) \
154 R123_CUDA_DEVICE void swap(r123array##_N##x##W& rhs) { \
156 for(size_t i = 0; i < _N; ++i) { \
162 R123_CUDA_DEVICE r123array##_N##x##W& incr(R123_ULONG_LONG n = 1) { \
166 if(sizeof(T) < sizeof(n) && n >> ((sizeof(T) < sizeof(n)) ? 8 * sizeof(T) : 0)) \
167 return incr_carefully(n); \
170 if(_N == 1 || R123_BUILTIN_EXPECT(!!v[0], 1)) \
174 if(_N == 1 || R123_BUILTIN_EXPECT(n <= v[0], 1)) \
186 ++v[_N > 1 ? 1 : 0]; \
187 if(_N == 2 || R123_BUILTIN_EXPECT(!!v[_N > 1 ? 1 : 0], 1)) \
189 ++v[_N > 2 ? 2 : 0]; \
190 if(_N == 3 || R123_BUILTIN_EXPECT(!!v[_N > 2 ? 2 : 0], 1)) \
192 ++v[_N > 3 ? 3 : 0]; \
193 for(size_t i = 4; i < _N; ++i) { \
194 if(R123_BUILTIN_EXPECT(!!v[i - 1], 1)) \
202 template<typename SeedSeq> R123_CUDA_DEVICE static r123array##_N##x##W seed(SeedSeq& ss) { \
203 r123array##_N##x##W ret; \
204 const size_t Ngen = _N * ((3 + sizeof(value_type)) / 4); \
205 uint32_t u32[Ngen]; \
206 uint32_t* p32 = &u32[0]; \
207 ss.generate(&u32[0], &u32[Ngen]); \
208 for(size_t i = 0; i < _N; ++i) { \
209 ret.v[i] = assemble_from_u32<value_type>(p32); \
210 p32 += (3 + sizeof(value_type)) / 4; \
216 R123_CUDA_DEVICE r123array##_N##x##W& incr_carefully(R123_ULONG_LONG n) { \
221 unsigned const rshift = 8 * ((sizeof(n) > sizeof(value_type)) ? sizeof(value_type) : 0); \
222 for(size_t i = 1; i < _N; ++i) { \
249template<
typename T>
struct r123arrayinsertable {
251 r123arrayinsertable(
const T& t_) : v(t_) { }
252 friend std::ostream& operator<<(std::ostream& os, r123arrayinsertable<T>
const& t) {
return os << t.v; }
255template<>
struct r123arrayinsertable<
uint8_t> {
257 r123arrayinsertable(
uint8_t const& t_) : v(t_) { }
258 friend std::ostream& operator<<(std::ostream& os, r123arrayinsertable<uint8_t>
const& t) {
return os << (int)t.v; }
261template<
typename T>
struct r123arrayextractable {
263 r123arrayextractable(T& t_) : v(t_) { }
264 friend std::istream& operator>>(std::istream& is, r123arrayextractable<T>& t) {
return is >> t.v; }
267template<>
struct r123arrayextractable<
uint8_t> {
269 r123arrayextractable(
uint8_t& t_) : v(t_) { }
270 friend std::istream& operator>>(std::istream& is, r123arrayextractable<uint8_t>& t) {
279#define CXXOVERLOADS(_N, W, T) \
281 inline std::ostream& operator<<(std::ostream& os, const r123array##_N##x##W& a) { \
282 os << r123arrayinsertable<T>(a.v[0]); \
283 for(size_t i = 1; i < _N; ++i) \
284 os << " " << r123arrayinsertable<T>(a.v[i]); \
288 inline std::istream& operator>>(std::istream& is, r123array##_N##x##W& a) { \
289 for(size_t i = 0; i < _N; ++i) { \
290 r123arrayextractable<T> x(a.v[i]); \
297 typedef r123array##_N##x##W Array##_N##x##W; \
315#define _r123array_tpl(_N, W, T) \
318 struct r123array##_N##x##W { \
320 CXXMETHODS(_N, W, T) \
321 CXXMETHODS_REQUIRING_STL \
324 CXXOVERLOADS(_N, W, T)
326#if defined(__CUDACC__)
328#pragma diag_suppress = code_is_unreachable
340#if defined(__CUDACC__)
341#pragma diag_default = code_is_unreachable
354#define R123_W(a) (8 * sizeof(((a*)0)->v[0]))
#define _r123array_tpl(_N, W, T)