ECOGEN 6.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
33#include <array>
34#include <iomanip>
35#include <cmath>
36#include <bitset>
37#include "vector.hpp"
38
39namespace decomposition
40{
41
42template <int Dim> struct Key
43{
44 public: // member types
45 //using value_type = uint_fast64_t;
46 using value_type = unsigned long long int;
48
49 using float_type = double;
50 template <typename U> using vector_type = math::vector<U, Dim>;
54 {
55 std::size_t operator()(Key const& n) const noexcept { return std::hash<value_type>()(n.index_); }
56 };
57
58 public: //static members
59 static value_type compute_index(const coordinate_type& _c) noexcept
60 {
61 value_type idx = split_bits(static_cast<value_type>(_c.x()));
62 for (int d = 1; d < Dim; ++d) {
63 idx |= (split_bits(static_cast<value_type>(_c[d])) << d);
64 }
65 return idx;
66 }
67
68 public:
69 static coordinate_type coordinate(const value_type& code) noexcept
70 {
71 coordinate_type c(0);
72 for (int d = 0; d < Dim; ++d) c[d] = static_cast<scalar_coordinate_type>(compress_bits(code >> static_cast<value_type>(d)));
73 return c;
74 }
75
76 public: // Ctors
77 Key() noexcept : index_(0) {}
78
79 Key(value_type idx) noexcept : index_(idx) {}
80
81 Key(int x, int y, int z) noexcept : Key(coordinate_type({x, y, z})) {}
82
84
85 Key(const Key&) = default;
86 Key(Key&&) = default;
87 Key& operator=(const Key&) & = default;
88 Key& operator=(Key&&) & = default;
89
90 public: //Access
91 coordinate_type coordinate() const noexcept { return coordinate(index_); }
92 const value_type& index() const noexcept { return index_; }
93 value_type& index() noexcept { return index_; }
94 const value_type& getIndex() const noexcept { return index_; }
95 value_type& getIndex() noexcept { return index_; }
96
97 Key neighbor(const coordinate_type& _offset) const noexcept
98 {
99 const auto c = coordinate() + _offset;
100 return Key(c);
101 }
102
103 Key child(int i) const noexcept { return (index_ << Dim) | static_cast<value_type>(i); }
104
105 Key& operator++() noexcept
106 {
107 ++index_;
108 return *this;
109 }
110 Key& operator--() noexcept
111 {
112 ++index_;
113 return *this;
114 }
115 Key& operator+=(int) noexcept
116 {
117 ++index_;
118 return *this;
119 }
120 Key& operator-=(int) noexcept
121 {
122 ++index_;
123 return *this;
124 }
125 friend std::ostream& operator<<(std::ostream& os, const Key& _k)
126 {
127 os << std::bitset<64>(_k.index_) << " = " << _k.index_ << " coord =( " << _k.coordinate() << " )";
128 return os;
129 }
130
131 private: //Static
132 template <int nDim = Dim> static value_type split_bits(value_type w)
133 {
134 using tag = std::integral_constant<int, 3>*;
135 return split_bits_impl(w, tag(0));
136 }
137 template <int nDim = Dim> static value_type compress_bits(value_type w)
138 {
139 using tag = std::integral_constant<int, 3>*;
140 return compress_bits_impl(w, tag(0));
141 }
142
143 static value_type split_bits_impl(value_type w, std::integral_constant<int, 3>*) noexcept
144 {
145 w &= 0x00000000001fffff;
146 w = (w | w << 32) & 0x001f00000000ffff;
147 w = (w | w << 16) & 0x001f0000ff0000ff;
148 w = (w | w << 8) & 0x010f00f00f00f00f;
149 w = (w | w << 4) & 0x10c30c30c30c30c3;
150 w = (w | w << 2) & 0x1249249249249249;
151 return w;
152 }
153 static scalar_coordinate_type compress_bits_impl(value_type w, std::integral_constant<int, 3>*) noexcept
154 {
155 w &= 0x1249249249249249;
156 w = (w ^ (w >> 2)) & 0x30c30c30c30c30c3;
157 w = (w ^ (w >> 4)) & 0xf00f00f00f00f00f;
158 w = (w ^ (w >> 8)) & 0x00ff0000ff0000ff;
159 w = (w ^ (w >> 16)) & 0x00ff00000000ffff;
160 w = (w ^ (w >> 32)) & 0x00000000001fffff;
161 return static_cast<scalar_coordinate_type>(w);
162 }
163 static value_type split_bits_impl(value_type x, std::integral_constant<int, 2>*) noexcept
164 {
165 x = (x | (x << 16)) & 0x0000FFFF0000FFFF;
166 x = (x | (x << 8)) & 0x00FF00FF00FF00FF;
167 x = (x | (x << 4)) & 0x0F0F0F0F0F0F0F0F;
168 x = (x | (x << 2)) & 0x3333333333333333;
169 x = (x | (x << 1)) & 0x5555555555555555;
170 return x;
171 }
172
173 static scalar_coordinate_type compress_bits_impl(value_type w, std::integral_constant<int, 2>*) noexcept
174 {
175 w &= 0x5555555555555555;
176 w = (w ^ (w >> 1)) & 0x3333333333333333;
177 w = (w ^ (w >> 2)) & 0x0f0f0f0f0f0f0f0f;
178 w = (w ^ (w >> 4)) & 0x00ff00ff00ff00ff;
179 w = (w ^ (w >> 8)) & 0x0000ffff0000ffff;
180 w = (w ^ (w >> 16)) & 0x00000000ffffffff;
181 return static_cast<scalar_coordinate_type>(w);
182 }
183
184 private:
186};
187
188// binary operators
189template <int Dim> Key<Dim> operator+(int n, Key<Dim> k) noexcept { return k += n; }
190
191template <int Dim> Key<Dim> operator-(int n, Key<Dim> k) noexcept { return k -= n; }
192
193// relational operators
194template <int Dim> constexpr bool operator==(const Key<Dim>& l, const Key<Dim>& r) noexcept { return l.index() == r.index(); }
195
196template <int Dim> constexpr bool operator!=(const Key<Dim>& l, const Key<Dim>& r) noexcept { return l.index() != r.index(); }
197
198template <int Dim> constexpr bool operator<(const Key<Dim>& l, const Key<Dim>& r) noexcept { return l.index() < r.index(); }
199
200template <int Dim> constexpr bool operator<=(const Key<Dim>& l, const Key<Dim>& r) noexcept { return l.index() <= r.index(); }
201
202template <int Dim> constexpr bool operator>(const Key<Dim>& l, const Key<Dim>& r) noexcept { return l.index() > r.index(); }
203
204template <int Dim> constexpr bool operator>=(const Key<Dim>& l, const Key<Dim>& r) noexcept { return l.index() >= r.index(); }
205
206} //namespace decomposition
207
208#endif
Definition vector.hpp:41
Definition decomposition.hpp:40
constexpr bool operator>(const Key< Dim > &l, const Key< Dim > &r) noexcept
Definition key.hpp:202
Key< Dim > operator+(int n, Key< Dim > k) noexcept
Definition key.hpp:189
Key< Dim > operator-(int n, Key< Dim > k) noexcept
Definition key.hpp:191
constexpr bool operator==(const Key< Dim > &l, const Key< Dim > &r) noexcept
Definition key.hpp:194
constexpr bool operator<=(const Key< Dim > &l, const Key< Dim > &r) noexcept
Definition key.hpp:200
constexpr bool operator<(const Key< Dim > &l, const Key< Dim > &r) noexcept
Definition key.hpp:198
constexpr bool operator>=(const Key< Dim > &l, const Key< Dim > &r) noexcept
Definition key.hpp:204
constexpr bool operator!=(const Key< Dim > &l, const Key< Dim > &r) noexcept
Definition key.hpp:196
std::size_t operator()(Key const &n) const noexcept
Definition key.hpp:55
Definition key.hpp:43
static value_type compute_index(const coordinate_type &_c) noexcept
Definition key.hpp:59
Key & operator-=(int) noexcept
Definition key.hpp:120
double float_type
Definition key.hpp:49
Key & operator++() noexcept
Definition key.hpp:105
Key(value_type idx) noexcept
Definition key.hpp:79
const value_type & getIndex() const noexcept
Definition key.hpp:94
Key(const Key &)=default
Key & operator=(const Key &) &=default
vector_type< float_type > real_coordinate_type
Definition key.hpp:52
vector_type< scalar_coordinate_type > coordinate_type
Definition key.hpp:51
Key & operator--() noexcept
Definition key.hpp:110
const value_type & index() const noexcept
Definition key.hpp:92
int scalar_coordinate_type
Definition key.hpp:47
value_type index_
Definition key.hpp:185
static value_type split_bits_impl(value_type w, std::integral_constant< int, 3 > *) noexcept
Definition key.hpp:143
Key & operator+=(int) noexcept
Definition key.hpp:115
static value_type split_bits_impl(value_type x, std::integral_constant< int, 2 > *) noexcept
Definition key.hpp:163
unsigned long long int value_type
Definition key.hpp:46
Key(coordinate_type x) noexcept
Definition key.hpp:83
static coordinate_type coordinate(const value_type &code) noexcept
Definition key.hpp:69
Key & operator=(Key &&) &=default
value_type & getIndex() noexcept
Definition key.hpp:95
Key(Key &&)=default
static scalar_coordinate_type compress_bits_impl(value_type w, std::integral_constant< int, 3 > *) noexcept
Definition key.hpp:153
static scalar_coordinate_type compress_bits_impl(value_type w, std::integral_constant< int, 2 > *) noexcept
Definition key.hpp:173
Key neighbor(const coordinate_type &_offset) const noexcept
Definition key.hpp:97
static value_type split_bits(value_type w)
Definition key.hpp:132
Key child(int i) const noexcept
Definition key.hpp:103
value_type & index() noexcept
Definition key.hpp:93
Key() noexcept
Definition key.hpp:77
Key(int x, int y, int z) noexcept
Definition key.hpp:81
math::vector< U, Dim > vector_type
Definition key.hpp:50
static value_type compress_bits(value_type w)
Definition key.hpp:137
coordinate_type coordinate() const noexcept
Definition key.hpp:91
friend std::ostream & operator<<(std::ostream &os, const Key &_k)
Definition key.hpp:125