DCCL v4
common.h
1 // Copyright 2009-2022:
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 <iostream>
31 #include <limits>
32 #include <type_traits>
33 
34 #include <google/protobuf/descriptor.h>
35 #include <google/protobuf/message.h>
36 
37 #include "bitset.h"
38 
39 namespace dccl
40 {
41 inline unsigned floor_bits2bytes(unsigned bits) { return bits >> 3; }
42 // more efficient way to do ceil(total_bits / 8)
43 // to get the number of bytes rounded up.
44 inline unsigned ceil_bits2bytes(unsigned bits)
45 {
46  enum
47  {
48  BYTE_MASK = 7
49  }; // 00000111
50  return (bits & BYTE_MASK) ? floor_bits2bytes(bits) + 1 : floor_bits2bytes(bits);
51 }
52 
53 // use the Google Protobuf types as they handle system quirks already
55 typedef google::protobuf::uint32 uint32;
57 using int32 = google::protobuf::int32;
59 using uint64 = google::protobuf::uint64;
61 using int64 = google::protobuf::int64;
62 
63 const unsigned BITS_IN_BYTE = 8;
64 
65 inline std::ostream& operator<<(std::ostream& out, const google::protobuf::Message& msg)
66 {
67  return (out << "[[" << msg.GetDescriptor()->name() << "]] " << msg.DebugString());
68 }
69 
70 template <typename Float> Float round(Float d) { return std::floor(d + 0.5); }
71 
76 template <typename Float>
77 typename std::enable_if<std::is_floating_point<Float>::value, Float>::type round(Float value,
78  int precision)
79 {
80  Float scaling = std::pow(10.0, precision);
81  return round(value * scaling) / scaling;
82 }
83 
88 template <typename Float>
89 typename std::enable_if<std::is_floating_point<Float>::value, Float>::type quantize(Float value,
90  double interval)
91 {
92  if (interval >= 1)
93  return round(value / interval) * interval;
94  else
95  {
96  double interval_inv = 1.0 / interval;
97  return round(value * interval_inv) / interval_inv;
98  }
99 }
100 
101 // C++98 has no long long overload for abs
102 template <typename Int> Int abs(Int i) { return (i < 0) ? -i : i; }
103 
108 template <typename Int>
109 typename std::enable_if<std::is_integral<Int>::value, Int>::type round(Int value, int precision)
110 {
111  if (precision >= 0)
112  {
113  // doesn't mean anything to round an integer to positive precision
114  return value;
115  }
116  else
117  {
118  Int scaling = (Int)std::pow(10.0, -precision);
119  Int remainder = value % scaling;
120 
121  value -= remainder;
122  if (remainder >= scaling / 2)
123  value += scaling;
124 
125  return value;
126  }
127 }
128 
133 template <typename Int>
134 typename std::enable_if<std::is_integral<Int>::value, Int>::type quantize(Int value,
135  double interval)
136 {
137  if ((interval - static_cast<uint64_t>(interval)) >= std::numeric_limits<double>::epsilon())
138  {
139  // doesn't mean anything to quantize an integer with a fractional interval
140  return value;
141  }
142 
143  Int remainder = value % static_cast<Int>(interval);
144  value -= remainder;
145  if (remainder >= interval / 2)
146  value += interval;
147  return value;
148 }
149 } // namespace dccl
150 #endif
dccl::uint64
google::protobuf::uint64 uint64
an unsigned 64 bit integer
Definition: common.h:59
dccl
Dynamic Compact Control Language namespace.
Definition: any.h:49
dccl::uint32
google::protobuf::uint32 uint32
an unsigned 32 bit integer
Definition: common.h:55
dccl::int64
google::protobuf::int64 int64
a signed 64 bit integer
Definition: common.h:61
Message
dccl::int32
google::protobuf::int32 int32
a signed 32 bit integer
Definition: common.h:57