summaryrefslogtreecommitdiff
path: root/modules/codec/c++/iterator.hpp
blob: 8d97bb39621a9c0e6a2617187ec1554be6cc924a (plain)
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
#pragma once

#include "data.hpp"

namespace saw {
namespace impl {
template<uint64_t i, uint64_t val_0, uint64_t... vals>
struct iterator_index_parameter_value {
	static_assert(i > 0, "Shouldn't happen");
	static constexpr uint64_t value = iterator_index_parameter_value<i-1u, vals...>::value;
};

template<uint64_t val_0, uint64_t... vals>
struct iterator_index_parameter_value<0u, val_0, vals...> {
	static constexpr uint64_t value = val_0;
};

template<typename Func, uint64_t... Dims>
struct iterator_in_bounds {
private:
	static constexpr std::array<uint64_t, sizeof...(Dims)> dims_{Dims...};

	template<uint64_t level>
	static error_or<void> apply_i(Func& func, data<schema::FixedArray<schema::UInt64, sizeof...(Dims)>, encode::Native>& index){
		if constexpr (level >= sizeof...(Dims)){
			return func(index);
		}else{
			index.at({level}).set(0);

			for(;index.at({level}).get() < impl::iterator_index_parameter_value<level,Dims...>::value; ++index.at({level})){
				auto eov = apply_i<level+1u>(func, index);
				if(eov.is_error()){
					return eov;
				}
			}
		}
		return saw::make_void();
	}
public:
	static error_or<void> apply(Func& func){
		data<schema::FixedArray<schema::UInt64,sizeof...(Dims)>, encode::Native> index;
		return apply_i<0u>(func, index);
	}
};
}

template<uint64_t... Dims>
struct rank_iterator {
	template<typename Func>
	static error_or<void> in_fixed_bounds(Func&& func){
		// static_assert(D == 2u, "Currently a lazy implementation for AND combinations of intervalls.");
		return impl::iterator_in_bounds<Func,Dims...>::apply(func);
	}
};
}