ECOGEN 4.0
Evolutive, Compressible, Open, Genuine, Easy, N-phase
Loading...
Searching...
No Matches
key.hpp
Go to the documentation of this file.
1//
2// ,---. ,--, .---. ,--, ,---. .-. .-.
3// | .-' .' .') / .-. ) .' .' | .-' | \| |
4// | `-. | |(_) | | |(_) | | __ | `-. | | |
5// | .-' \ \ | | | | \ \ ( _) | .-' | |\ |
6// | `--. \ `-. \ `-' / \ `-) ) | `--. | | |)|
7// /( __.' \____\ )---' )\____/ /( __.' /( (_)
8// (__) (_) (__) (__) (__)
9//
10// This file is part of ECOGEN.
11//
12// ECOGEN is the legal property of its developers, whose names
13// are listed in the copyright file included with this source
14// distribution.
15//
16// ECOGEN is free software: you can redistribute it and/or modify
17// it under the terms of the GNU General Public License as published
18// by the Free Software Foundation, either version 3 of the License,
19// or (at your option) any later version.
20//
21// ECOGEN is distributed in the hope that it will be useful,
22// but WITHOUT ANY WARRANTY; without even the implied warranty of
23// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24// GNU General Public License for more details.
25//
26// You should have received a copy of the GNU General Public License
27// along with ECOGEN (file LICENSE).
28// If not, see <http://www.gnu.org/licenses/>.
29
30#ifndef INCLUDED_KEY_HPP
31#define INCLUDED_KEY_HPP
32
37
38#include <array>
39#include <iomanip>
40#include <cmath>
41#include <bitset>
42#include "vector.hpp"
43
44namespace decomposition
45{
46
47
48template <int Dim>
49struct Key
50{
51public: // member types
52
53 //using value_type = uint_fast64_t;
54 using value_type = unsigned long long int;
56
57 using float_type = double;
58 template<typename U>
63 {
64 std::size_t operator()(Key const& n) const noexcept
65 {
66 return std::hash<value_type>()(n.index_);
67 }
68 };
69
70public: //static members
71
72 static value_type compute_index(const coordinate_type& _c)noexcept {
73 value_type idx =split_bits(static_cast<value_type>(_c.x()));
74 for(int d=1;d<Dim;++d)
75 {
76 idx |=(split_bits(static_cast<value_type>(_c[d])) << d);
77 }
78 return idx;
79 }
80
81public:
82 static coordinate_type coordinate(const value_type& code ) noexcept{
83 coordinate_type c(0);
84 for (int d = 0; d < Dim; ++d) c[d] = static_cast<scalar_coordinate_type>(compress_bits(code >> static_cast<value_type>(d)));
85 return c;
86 }
87
88public: // Ctors
89
90 Key() noexcept
91 : index_(0) {}
92
93 Key(value_type idx) noexcept
94 : index_(idx) {}
95
96 Key(int x, int y, int z) noexcept
97 :Key(coordinate_type({x,y,z})) { }
98
99 Key(coordinate_type x) noexcept
100 : index_(compute_index(x)) { }
101
102 Key(const Key&) = default;
103 Key(Key&&) = default;
104 Key& operator=(const Key&) & = default;
105 Key& operator=(Key&&) & = default;
106
107
108public: //Access
109
110 coordinate_type coordinate()const noexcept {return coordinate(index_);}
111 const value_type& index()const noexcept{return index_;}
112 value_type& index() noexcept{return index_;}
113 const value_type& getIndex()const noexcept {return index_;}
114 value_type& getIndex() noexcept{return index_;}
115
116 Key neighbor(const coordinate_type& _offset) const noexcept
117 {
118 const auto c =coordinate()+_offset;
119 return Key(c);
120 }
121
122 Key child(int i) const noexcept
123 {
124 return (index_<<Dim)| static_cast<value_type>(i);
125 }
126
127 Key& operator++() noexcept { ++index_;return *this; }
128 Key& operator--() noexcept { ++index_;return *this; }
129 Key& operator+=(int) noexcept { ++index_; return *this;}
130 Key& operator-=(int) noexcept { ++index_; return *this;}
131 friend std::ostream& operator<<(std::ostream& os, const Key& _k)
132 {
133 os<<std::bitset<64>(_k.index_)<<" = "<<_k.index_
134 <<" coord =( "<<_k.coordinate()<<" )";
135 return os;
136 }
137
138
139private: //Static
140
141 template<int nDim =Dim>
143 {
144 using tag=std::integral_constant<int,3>*;
145 return split_bits_impl(w, tag(0));
146 }
147 template<int nDim =Dim>
149 {
150 using tag=std::integral_constant<int,3>*;
151 return compress_bits_impl(w, tag(0));
152 }
153
154 static value_type
155 split_bits_impl(value_type w, std::integral_constant<int, 3>*)
156 noexcept
157 {
158 w &= 0x00000000001fffff;
159 w = (w | w << 32) & 0x001f00000000ffff;
160 w = (w | w << 16) & 0x001f0000ff0000ff;
161 w = (w | w << 8) & 0x010f00f00f00f00f;
162 w = (w | w << 4) & 0x10c30c30c30c30c3;
163 w = (w | w << 2) & 0x1249249249249249;
164 return w;
165 }
167 compress_bits_impl(value_type w,std::integral_constant<int, 3>*) noexcept
168 {
169 w &= 0x1249249249249249;
170 w = (w ^ (w >> 2)) & 0x30c30c30c30c30c3;
171 w = (w ^ (w >> 4)) & 0xf00f00f00f00f00f;
172 w = (w ^ (w >> 8)) & 0x00ff0000ff0000ff;
173 w = (w ^ (w >> 16)) & 0x00ff00000000ffff;
174 w = (w ^ (w >> 32)) & 0x00000000001fffff;
175 return static_cast<scalar_coordinate_type>(w);
176 }
177 static value_type
178 split_bits_impl(value_type x, std::integral_constant<int, 2>*)
179 noexcept
180 {
181 x = (x | (x << 16)) & 0x0000FFFF0000FFFF;
182 x = (x | (x << 8)) & 0x00FF00FF00FF00FF;
183 x = (x | (x << 4)) & 0x0F0F0F0F0F0F0F0F;
184 x = (x | (x << 2)) & 0x3333333333333333;
185 x = (x | (x << 1)) & 0x5555555555555555;
186 return x;
187 }
188
190 compress_bits_impl(value_type w,std::integral_constant<int, 2>*) noexcept
191 {
192 w &= 0x5555555555555555;
193 w = (w ^ (w >> 1)) & 0x3333333333333333;
194 w = (w ^ (w >> 2)) & 0x0f0f0f0f0f0f0f0f;
195 w = (w ^ (w >> 4)) & 0x00ff00ff00ff00ff;
196 w = (w ^ (w >> 8)) & 0x0000ffff0000ffff;
197 w = (w ^ (w >> 16)) & 0x00000000ffffffff;
198 return static_cast<scalar_coordinate_type>(w);
199 }
200
201private:
203};
204
205// binary operators
206template<int Dim>
207Key<Dim> operator+(int n, Key<Dim> k) noexcept
208{ return k+=n;}
209
210template<int Dim>
211Key<Dim> operator-(int n, Key<Dim> k) noexcept
212{ return k-=n; }
213
214// relational operators
215template<int Dim>
216constexpr bool operator==(const Key<Dim>& l, const Key<Dim>& r) noexcept
217{ return l.index() == r.index(); }
218
219template<int Dim>
220constexpr bool operator!=(const Key<Dim>& l, const Key<Dim>& r) noexcept
221{ return l.index() != r.index(); }
222
223template<int Dim>
224constexpr bool operator<(const Key<Dim>& l, const Key<Dim>& r) noexcept
225{ return l.index() < r.index(); }
226
227template<int Dim>
228constexpr bool operator<=(const Key<Dim>& l, const Key<Dim>& r) noexcept
229{ return l.index() <= r.index(); }
230
231template<int Dim>
232constexpr bool operator>(const Key<Dim>& l, const Key<Dim>& r) noexcept
233{ return l.index() > r.index(); }
234
235template<int Dim>
236constexpr bool operator>=(const Key<Dim>& l, const Key<Dim>& r) noexcept
237{ return l.index() >= r.index(); }
238
239}
240
241#endif
Definition vector.hpp:42
Definition decomposition.hpp:40
constexpr bool operator>(const Key< Dim > &l, const Key< Dim > &r) noexcept
Definition key.hpp:232
Key< Dim > operator+(int n, Key< Dim > k) noexcept
Definition key.hpp:207
Key< Dim > operator-(int n, Key< Dim > k) noexcept
Definition key.hpp:211
constexpr bool operator==(const Key< Dim > &l, const Key< Dim > &r) noexcept
Definition key.hpp:216
constexpr bool operator<=(const Key< Dim > &l, const Key< Dim > &r) noexcept
Definition key.hpp:228
constexpr bool operator<(const Key< Dim > &l, const Key< Dim > &r) noexcept
Definition key.hpp:224
constexpr bool operator>=(const Key< Dim > &l, const Key< Dim > &r) noexcept
Definition key.hpp:236
constexpr bool operator!=(const Key< Dim > &l, const Key< Dim > &r) noexcept
Definition key.hpp:220
std::size_t operator()(Key const &n) const noexcept
Definition key.hpp:64
Definition key.hpp:50
static value_type compute_index(const coordinate_type &_c) noexcept
Definition key.hpp:72
Key & operator-=(int) noexcept
Definition key.hpp:130
double float_type
Definition key.hpp:57
Key & operator++() noexcept
Definition key.hpp:127
Key(value_type idx) noexcept
Definition key.hpp:93
const value_type & getIndex() const noexcept
Definition key.hpp:113
Key(const Key &)=default
Key & operator=(const Key &) &=default
vector_type< scalar_coordinate_type > coordinate_type
Definition key.hpp:60
Key & operator--() noexcept
Definition key.hpp:128
const value_type & index() const noexcept
Definition key.hpp:111
int scalar_coordinate_type
Definition key.hpp:55
value_type index_
Definition key.hpp:202
static value_type split_bits_impl(value_type w, std::integral_constant< int, 3 > *) noexcept
Definition key.hpp:155
Key & operator+=(int) noexcept
Definition key.hpp:129
static value_type split_bits_impl(value_type x, std::integral_constant< int, 2 > *) noexcept
Definition key.hpp:178
unsigned long long int value_type
Definition key.hpp:54
Key(coordinate_type x) noexcept
Definition key.hpp:99
static coordinate_type coordinate(const value_type &code) noexcept
Definition key.hpp:82
Key & operator=(Key &&) &=default
value_type & getIndex() noexcept
Definition key.hpp:114
Key(Key &&)=default
static scalar_coordinate_type compress_bits_impl(value_type w, std::integral_constant< int, 3 > *) noexcept
Definition key.hpp:167
static scalar_coordinate_type compress_bits_impl(value_type w, std::integral_constant< int, 2 > *) noexcept
Definition key.hpp:190
Key neighbor(const coordinate_type &_offset) const noexcept
Definition key.hpp:116
static value_type split_bits(value_type w)
Definition key.hpp:142
Key child(int i) const noexcept
Definition key.hpp:122
value_type & index() noexcept
Definition key.hpp:112
Key() noexcept
Definition key.hpp:90
Key(int x, int y, int z) noexcept
Definition key.hpp:96
static value_type compress_bits(value_type w)
Definition key.hpp:148
coordinate_type coordinate() const noexcept
Definition key.hpp:110
friend std::ostream & operator<<(std::ostream &os, const Key &_k)
Definition key.hpp:131