ztsdb
misc.hpp
1 // (C) 2016 Leonardo Silvestri
2 //
3 // This file is part of ztsdb.
4 //
5 // ztsdb is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // ztsdb is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with ztsdb. If not, see <http://www.gnu.org/licenses/>.
17 
18 
19 #ifndef MISC_HPP
20 #define MISC_HPP
21 
22 
23 #include <string>
24 #include <cstdint>
25 #include <cmath>
26 #include <endian.h>
27 #include <string>
28 #include <stdexcept>
29 #include <iostream>
30 #include <functional>
31 #include <sstream>
32 #include <netinet/in.h>
33 #include "globals.hpp"
34 
35 
36 // LLL put this in an namespace!
37 
38 
39 // we favour intel CPUs here; what is sent on the wire is not network
40 // order but little endian; big endian processors will change order
41 // while little endian processor will have no op.
42 
43 #if __BYTE_ORDER == __BIG_ENDIAN
44 
45 inline uint64_t hton64(uint64_t x) {
46  return htobe64(x);
47 }
48 
49 inline uint64_t ntoh64(uint64_t x) {
50  return htobe64(x);
51 }
52 
53 template<typename T>
54 inline T hton(T x) {
55  switch (sizeof(T)) {
56  case 4: {
57  union { T t; uint32_t i; };
58  i = htobe32(reinterpret_cast<uint32_t&>(x));
59  return t;
60  }
61  case 8: {
62  union { T t; uint64_t i; };
63  i = htobe64(reinterpret_cast<uint64_t&>(x));
64  return t;
65  }
66  default:
67  throw std::domain_error("can't handle hton for element of size: " + std::to_string(sizeof(T)));
68  }
69 }
70 
71 template<>
72 inline Global::dtime hton(Global::dtime x) {
73  auto i = htobe64(x.time_since_epoch().count());
74  auto d = Global::dtime::duration{i};
75  return Global::dtime(d);
76 }
77 
78 template<typename T>
79 inline T ntoh(T x) {
80  return hton(x);
81 }
82 
83 
84 #elif __BYTE_ORDER == __LITTLE_ENDIAN
85 
86 inline uint64_t hton64(size_t x) {
87  return x;
88 }
89 
90 inline uint64_t ntoh64(size_t x) {
91  return x;
92 }
93 
94 template<typename T>
95 inline T hton(T x) {
96  return x;
97 }
98 
99 template<typename T>
100 inline T ntoh(T x) {
101  return x;
102 }
103 
104 #else
105 #error __BYTE_ORDER is neither __LITTLE_ENDIAN nor __BIG_ENDIAN
106 #endif
107 
108 
109 std::string printBuf(const char* buf, unsigned len);
110 
111 inline unsigned getAlignedLength(size_t n, unsigned nbyteAlignment) {
112  auto rem = n % nbyteAlignment;
113  return rem ? n + nbyteAlignment - rem : n;
114 }
115 
116 bool operator<(const sockaddr_in& sa1, const sockaddr_in& sa2);
117 
118 inline size_t ltostr_r(long val, char* buf, size_t sz) {
119  if (val == 0) {
120  buf[0] = '0';
121  return 1;
122  }
123  else {
124  size_t e = std::abs(val) <= 1 ? 0 : log10(std::abs(val));
125  if (val < 0) {
126  ++e;
127  buf[0] = '-';
128  val = -val;
129  }
130  auto idx = e;
131  if (idx >= sz) {
132  throw std::range_error("ltostr_r: buffer too small");
133  }
134  while (val > 0) {
135  buf[idx] = (val % 10) + '0';
136  val /= 10;
137  --idx;
138  }
139  return e + 1;
140  }
141 }
142 
143 bool readNumber(const char*& s, const char* e, int& n, bool dosign=false);
144 
145 namespace ztsdb {
146 
151  template<typename T, typename U, typename R>
152  struct plus {
153  inline R operator()(const T& t, const U& u) const {
154  return t + u;
155  }
156  };
157 
158  template<typename T, typename U, typename R>
159  struct minus {
160  inline R operator()(const T& t, const U& u) const {
161  return t - u;
162  }
163  };
164 
165  template<typename T, typename U, typename R>
166  struct multiplies {
167  inline R operator()(const T& t, const U& u) const {
168  return t * u;
169  }
170  };
171 
172  template<typename T, typename U, typename R>
173  struct divides {
174  inline R operator()(const T& t, const U& u) const {
175  return t / u;
176  }
177  };
178 
179  template<typename T, typename U, typename R>
180  struct modulus {
181  inline R operator()(const T& t, const U& u) const {
182  return fmod(t, u);
183  }
184  };
185 
186  template<typename T>
187  struct max {
188  inline T operator()(const T& t, const T& u) const {
189  if (std::isnan(t) || std::isnan(u)) {
190  return Global::ZNAN;
191  }
192  return std::max(t, u);
193  }
194  };
195 
196  template<typename T>
197  struct min {
198  inline T operator()(const T& t, const T& u) const {
199  if (std::isnan(t) || std::isnan(u)) {
200  return Global::ZNAN;
201  }
202  return std::min(t, u);
203  }
204  };
205 }
206 
207 
208 template<typename T>
209 static inline std::function<T()> GenNbFun() {
210  T count = 0;
211  return [=]() mutable { return ++count; };
212 }
213 
214 inline std::function<std::string(std::string)> GensymFun() {
215  auto count = 0;
216  return
217  [=](std::string s) mutable {
218  std::stringstream ss;
219  ss << s << ++count;
220  return ss.str();
221  };
222 }
223 
224 
225 template <typename Int>
226 constexpr Int next_power2(Int i) {
227  --i;
228  Int n = 1;
229  while (i > 0) { n <<= 1; i >>= 1; }
230  return n;
231 }
232 
233 
234 #endif
235 
ztsdb::max
Definition: misc.hpp:187
ztsdb::multiplies
Definition: misc.hpp:166
ztsdb::divides
Definition: misc.hpp:173
val
Contains the types that constitute the output of an evaluation by the interpreter.
Definition: display.hpp:31
ztsdb::min
Definition: misc.hpp:197
ztsdb::modulus
Definition: misc.hpp:180
ztsdb::minus
Definition: misc.hpp:159
ztsdb::plus
Definition: misc.hpp:152