DCCL v4
common.h
1 // Copyright 2009-2023:
2 // GobySoft, LLC (2013-)
3 // Massachusetts Institute of Technology (2007-2014)
4 // Community contributors (see AUTHORS file)
5 // File authors:
6 // Toby Schneider <toby@gobysoft.org>
7 // Davide Fenucci <davfen@noc.ac.uk>
8 // Chris Murphy <cmurphy@aphysci.com>
9 //
10 //
11 // This file is part of the Dynamic Compact Control Language Library
12 // ("DCCL").
13 //
14 // DCCL is free software: you can redistribute it and/or modify
15 // it under the terms of the GNU Lesser General Public License as published by
16 // the Free Software Foundation, either version 2.1 of the License, or
17 // (at your option) any later version.
18 //
19 // DCCL is distributed in the hope that it will be useful,
20 // but WITHOUT ANY WARRANTY; without even the implied warranty of
21 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 // GNU Lesser General Public License for more details.
23 //
24 // You should have received a copy of the GNU Lesser General Public License
25 // along with DCCL. If not, see <http://www.gnu.org/licenses/>.
26 #ifndef DCCLConstants20091211H
27 #define DCCLConstants20091211H
28 
29 #include <cmath>
30 #include <functional>
31 #include <iostream>
32 #include <limits>
33 #include <type_traits>
34 
35 #include <google/protobuf/descriptor.h>
36 #include <google/protobuf/message.h>
37 
38 #include "bitset.h"
39 
40 namespace dccl
41 {
42 inline unsigned floor_bits2bytes(unsigned bits) { return bits >> 3; }
43 // more efficient way to do ceil(total_bits / 8)
44 // to get the number of bytes rounded up.
45 inline unsigned ceil_bits2bytes(unsigned bits)
46 {
47  enum
48  {
49  BYTE_MASK = 7
50  }; // 00000111
51  return (bits & BYTE_MASK) ? floor_bits2bytes(bits) + 1 : floor_bits2bytes(bits);
52 }
53 
54 // use the Google Protobuf types as they handle system quirks already
56 typedef google::protobuf::uint32 uint32;
58 using int32 = google::protobuf::int32;
60 using uint64 = google::protobuf::uint64;
62 using int64 = google::protobuf::int64;
63 
64 const unsigned BITS_IN_BYTE = 8;
65 
66 inline std::ostream& operator<<(std::ostream& out, const google::protobuf::Message& msg)
67 {
68  return (out << "[[" << msg.GetDescriptor()->name() << "]] " << msg.DebugString());
69 }
70 
71 template <typename Float> Float round(Float d) { return std::floor(d + 0.5); }
72 
77 template <typename Float>
78 typename std::enable_if<std::is_floating_point<Float>::value, Float>::type round(Float value,
79  int precision)
80 {
81  Float scaling = std::pow(10.0, precision);
82  return round(value * scaling) / scaling;
83 }
84 
89 template <typename Float>
90 typename std::enable_if<std::is_floating_point<Float>::value, Float>::type quantize(Float value,
91  double interval)
92 {
93  if (interval >= 1)
94  return round(value / interval) * interval;
95  else
96  {
97  double interval_inv = 1.0 / interval;
98  return round(value * interval_inv) / interval_inv;
99  }
100 }
101 
102 // C++98 has no long long overload for abs
103 template <typename Int> Int abs(Int i) { return (i < 0) ? -i : i; }
104 
109 template <typename Int>
110 typename std::enable_if<std::is_integral<Int>::value, Int>::type round(Int value, int precision)
111 {
112  if (precision >= 0)
113  {
114  // doesn't mean anything to round an integer to positive precision
115  return value;
116  }
117  else
118  {
119  Int scaling = (Int)std::pow(10.0, -precision);
120  Int remainder = value % scaling;
121 
122  value -= remainder;
123  if (remainder >= scaling / 2)
124  value += scaling;
125 
126  return value;
127  }
128 }
129 
134 template <typename Int>
135 typename std::enable_if<std::is_integral<Int>::value, Int>::type quantize(Int value,
136  double interval)
137 {
138  if ((interval - static_cast<uint64_t>(interval)) >= std::numeric_limits<double>::epsilon())
139  {
140  // doesn't mean anything to quantize an integer with a fractional interval
141  return value;
142  }
143 
144  Int remainder = value % static_cast<Int>(interval);
145  value -= remainder;
146  if (remainder >= interval / 2)
147  value += interval;
148  return value;
149 }
150 
152 template <class T> inline void hash_combine(std::size_t& seed, const T& v)
153 {
154  std::hash<T> hasher;
155  seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
156 }
157 
158 } // namespace dccl
159 #endif
dccl::uint64
google::protobuf::uint64 uint64
an unsigned 64 bit integer
Definition: common.h:60
dccl
Dynamic Compact Control Language namespace.
Definition: any.h:46
dccl::uint32
google::protobuf::uint32 uint32
an unsigned 32 bit integer
Definition: common.h:56
dccl::int64
google::protobuf::int64 int64
a signed 64 bit integer
Definition: common.h:62
Message
dccl::int32
google::protobuf::int32 int32
a signed 32 bit integer
Definition: common.h:58