Loading [MathJax]/extensions/TeX/AMSsymbols.js
Open3D (C++ API)  0.14.1
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
Scalar.h
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - Open3D: www.open3d.org -
3 // ----------------------------------------------------------------------------
4 // The MIT License (MIT)
5 //
6 // Copyright (c) 2018-2021 www.open3d.org
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
14 //
15 // The above copyright notice and this permission notice shall be included in
16 // all copies or substantial portions of the Software.
17 //
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 // IN THE SOFTWARE.
25 // ----------------------------------------------------------------------------
26 
27 #pragma once
28 
29 #include <cstdint>
30 #include <limits>
31 #include <string>
32 
33 #include "open3d/core/Dtype.h"
34 #include "open3d/utility/Logging.h"
35 
36 namespace open3d {
37 namespace core {
38 
42 class Scalar {
43 public:
44  enum class ScalarType { Double, Int64, Bool };
45 
46  Scalar(float v) {
47  scalar_type_ = ScalarType::Double;
48  value_.d = static_cast<double>(v);
49  }
50  Scalar(double v) {
51  scalar_type_ = ScalarType::Double;
52  value_.d = static_cast<double>(v);
53  }
54  Scalar(int8_t v) {
55  scalar_type_ = ScalarType::Int64;
56  value_.i = static_cast<int64_t>(v);
57  }
58  Scalar(int16_t v) {
59  scalar_type_ = ScalarType::Int64;
60  value_.i = static_cast<int64_t>(v);
61  }
63  scalar_type_ = ScalarType::Int64;
64  value_.i = static_cast<int64_t>(v);
65  }
66  Scalar(int64_t v) {
67  scalar_type_ = ScalarType::Int64;
68  value_.i = static_cast<int64_t>(v);
69  }
70 
71  // This constructor is required to ensure long input support where int64_t
72  // is not equal to long (e.g. mac os where int64_t is long long).
73  // The template argument with enable_if ensures that this constructor is
74  // enabled only when int64_t is not equal to long.
75  // Ref: https://en.cppreference.com/w/cpp/types/enable_if
76  template <typename T = int64_t>
77  Scalar(long v,
78  typename std::enable_if<!std::is_same<T, long>::value>::type* = 0) {
79  scalar_type_ = ScalarType::Int64;
80  value_.i = static_cast<int64_t>(v);
81  }
82  Scalar(uint8_t v) {
83  scalar_type_ = ScalarType::Int64;
84  value_.i = static_cast<int64_t>(v);
85  }
86  Scalar(uint16_t v) {
87  scalar_type_ = ScalarType::Int64;
88  value_.i = static_cast<int64_t>(v);
89  }
91  scalar_type_ = ScalarType::Int64;
92  value_.i = static_cast<int64_t>(v);
93  }
95  scalar_type_ = ScalarType::Int64;
96  // Conversion uint64_t -> int64_t is undefined behaviour until C++20.
97  // Compilers optimize this to a single cast.
98  if (v <= static_cast<uint64_t>(std::numeric_limits<int64_t>::max())) {
99  value_.i = static_cast<int64_t>(v);
100  } else {
101  // Safe conversion to two's complement:
102  // - Compute x = uint_max - v such that x <= int_max
103  // - Safely cast x from unsigned to signed
104  // - Map x to y such that casting y to signed leads y = v
105  value_.i = -static_cast<int64_t>(
106  std::numeric_limits<uint64_t>::max() - v) -
107  1;
108  }
109  }
110  Scalar(bool v) {
111  scalar_type_ = ScalarType::Bool;
112  value_.b = static_cast<bool>(v);
113  }
114 
115  bool IsDouble() const { return scalar_type_ == ScalarType::Double; }
116  bool IsInt64() const { return scalar_type_ == ScalarType::Int64; }
117  bool IsBool() const { return scalar_type_ == ScalarType::Bool; }
118 
121  double GetDouble() const {
122  if (!IsDouble()) {
123  utility::LogError("Scalar is not a ScalarType:Double type.");
124  }
125  return value_.d;
126  }
129  int64_t GetInt64() const {
130  if (!IsInt64()) {
131  utility::LogError("Scalar is not a ScalarType:Int64 type.");
132  }
133  return value_.i;
134  }
137  bool GetBool() const {
138  if (!IsBool()) {
139  utility::LogError("Scalar is not a ScalarType:Bool type.");
140  }
141  return value_.b;
142  }
143 
145  template <typename T>
146  T To() const {
147  if (scalar_type_ == ScalarType::Double) {
148  return static_cast<T>(value_.d);
149  } else if (scalar_type_ == ScalarType::Int64) {
150  return static_cast<T>(value_.i);
151  } else if (scalar_type_ == ScalarType::Bool) {
152  return static_cast<T>(value_.b);
153  } else {
154  utility::LogError("To: ScalarType not supported.");
155  }
156  }
157 
159  const std::string& error_msg) const {
160  if (scalar_type_ != other.scalar_type_) {
161  if (error_msg.empty()) {
162  utility::LogError("Scalar mode {} are not the same as {}.",
163  ToString(), other.ToString());
164  } else {
165  utility::LogError("Scalar mode {} are not the same as {}: {}",
166  ToString(), other.ToString(), error_msg);
167  }
168  }
169  }
170 
171  std::string ToString() const {
172  std::string scalar_type_str;
173  std::string value_str;
174  if (scalar_type_ == ScalarType::Double) {
175  scalar_type_str = "Double";
176  value_str = std::to_string(value_.d);
177  } else if (scalar_type_ == ScalarType::Int64) {
178  scalar_type_str = "Int64";
179  value_str = std::to_string(value_.i);
180  } else if (scalar_type_ == ScalarType::Bool) {
181  scalar_type_str = "Bool";
182  value_str = value_.b ? "true" : "false";
183  } else {
184  utility::LogError("ScalarTypeToString: ScalarType not supported.");
185  }
186  return scalar_type_str + ":" + value_str;
187  }
188 
189  template <typename T>
190  bool Equal(T value) const {
191  if (scalar_type_ == ScalarType::Double) {
192  return value_.d == value;
193  } else if (scalar_type_ == ScalarType::Int64) {
194  return value_.i == value;
195  } else if (scalar_type_ == ScalarType::Bool) {
196  return false; // Boolean does not equal to non-boolean values.
197  } else {
198  utility::LogError("Equals: ScalarType not supported.");
199  }
200  }
201 
202  bool Equal(bool value) const {
203  return scalar_type_ == ScalarType::Bool && value_.b == value;
204  }
205 
206  bool Equal(Scalar other) const {
207  if (other.scalar_type_ == ScalarType::Double) {
208  return Equal(other.GetDouble());
209  } else if (other.scalar_type_ == ScalarType::Int64) {
210  return Equal(other.GetInt64());
211  } else if (other.scalar_type_ == ScalarType::Bool) {
212  return scalar_type_ == ScalarType::Bool &&
213  value_.b == other.value_.b;
214  } else {
215  utility::LogError("Equals: ScalarType not supported.");
216  }
217  }
218 
219 private:
220  ScalarType scalar_type_;
221  union value_t {
222  double d;
223  int64_t i;
224  bool b;
225  } value_;
226 };
227 
228 } // namespace core
229 } // namespace open3d
Scalar(int32_t v)
Definition: Scalar.h:62
bool IsBool() const
Definition: Scalar.h:117
const char const char value recording_handle imu_sample recording_handle uint8_t size_t data_size k4a_record_configuration_t config target_format k4a_capture_t capture_handle k4a_imu_sample_t imu_sample playback_handle k4a_logging_message_cb_t void min_level device_handle k4a_imu_sample_t timeout_in_ms capture_handle capture_handle capture_handle image_handle temperature_c k4a_image_t image_handle uint8_t image_handle image_handle image_handle image_handle uint32_t
Definition: K4aPlugin.cpp:557
Scalar(int64_t v)
Definition: Scalar.h:66
const char const char value recording_handle imu_sample recording_handle uint8_t size_t data_size k4a_record_configuration_t config target_format k4a_capture_t capture_handle k4a_imu_sample_t imu_sample playback_handle k4a_logging_message_cb_t void min_level device_handle k4a_imu_sample_t int32_t
Definition: K4aPlugin.cpp:398
Scalar(uint16_t v)
Definition: Scalar.h:86
Definition: Scalar.h:42
Scalar(bool v)
Definition: Scalar.h:110
T To() const
To<T>() does not check for scalar type and overflows.
Definition: Scalar.h:146
Scalar(uint32_t v)
Definition: Scalar.h:90
Scalar(uint64_t v)
Definition: Scalar.h:94
Scalar(uint8_t v)
Definition: Scalar.h:82
Scalar(int16_t v)
Definition: Scalar.h:58
const char const char value recording_handle imu_sample recording_handle uint8_t size_t data_size k4a_record_configuration_t config target_format k4a_capture_t capture_handle k4a_imu_sample_t imu_sample uint64_t
Definition: K4aPlugin.cpp:352
bool IsDouble() const
Definition: Scalar.h:115
bool Equal(bool value) const
Definition: Scalar.h:202
bool IsInt64() const
Definition: Scalar.h:116
char type
Definition: FilePCD.cpp:60
double GetDouble() const
Definition: Scalar.h:121
bool GetBool() const
Definition: Scalar.h:137
Scalar(double v)
Definition: Scalar.h:50
Scalar(float v)
Definition: Scalar.h:46
Definition: PinholeCameraIntrinsic.cpp:35
bool Equal(T value) const
Definition: Scalar.h:190
ScalarType
Definition: Scalar.h:44
bool Equal(Scalar other) const
Definition: Scalar.h:206
Scalar(int8_t v)
Definition: Scalar.h:54
Scalar(long v, typename std::enable_if<!std::is_same< T, long >::value >::type *=0)
Definition: Scalar.h:77
std::string ToString() const
Definition: Scalar.h:171
int64_t GetInt64() const
Definition: Scalar.h:129
#define LogError(...)
Definition: Logging.h:72
void AssertSameScalarType(Scalar other, const std::string &error_msg) const
Definition: Scalar.h:158