Open3D (C++ API)  0.18.0
Scalar.h
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - Open3D: www.open3d.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2023 www.open3d.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #pragma once
9 
10 #include <cstdint>
11 #include <limits>
12 #include <string>
13 
14 #include "open3d/core/Dtype.h"
15 #include "open3d/utility/Logging.h"
16 
17 namespace open3d {
18 namespace core {
19 
23 class Scalar {
24 public:
25  enum class ScalarType { Double, Int64, Bool };
26 
27  Scalar(float v) {
28  scalar_type_ = ScalarType::Double;
29  value_.d = static_cast<double>(v);
30  }
31  Scalar(double v) {
32  scalar_type_ = ScalarType::Double;
33  value_.d = static_cast<double>(v);
34  }
35  Scalar(int8_t v) {
36  scalar_type_ = ScalarType::Int64;
37  value_.i = static_cast<int64_t>(v);
38  }
39  Scalar(int16_t v) {
40  scalar_type_ = ScalarType::Int64;
41  value_.i = static_cast<int64_t>(v);
42  }
44  scalar_type_ = ScalarType::Int64;
45  value_.i = static_cast<int64_t>(v);
46  }
47  Scalar(int64_t v) {
48  scalar_type_ = ScalarType::Int64;
49  value_.i = static_cast<int64_t>(v);
50  }
51 
52  // This constructor is required to ensure long input support where int64_t
53  // is not equal to long (e.g. mac os where int64_t is long long).
54  // The template argument with enable_if ensures that this constructor is
55  // enabled only when int64_t is not equal to long.
56  // Ref: https://en.cppreference.com/w/cpp/types/enable_if
57  template <typename T = int64_t>
58  Scalar(long v,
59  typename std::enable_if<!std::is_same<T, long>::value>::type* = 0) {
60  scalar_type_ = ScalarType::Int64;
61  value_.i = static_cast<int64_t>(v);
62  }
63  Scalar(uint8_t v) {
64  scalar_type_ = ScalarType::Int64;
65  value_.i = static_cast<int64_t>(v);
66  }
67  Scalar(uint16_t v) {
68  scalar_type_ = ScalarType::Int64;
69  value_.i = static_cast<int64_t>(v);
70  }
72  scalar_type_ = ScalarType::Int64;
73  value_.i = static_cast<int64_t>(v);
74  }
76  scalar_type_ = ScalarType::Int64;
77  // Conversion uint64_t -> int64_t is undefined behaviour until C++20.
78  // Compilers optimize this to a single cast.
79  if (v <= static_cast<uint64_t>(std::numeric_limits<int64_t>::max())) {
80  value_.i = static_cast<int64_t>(v);
81  } else {
82  // Safe conversion to two's complement:
83  // - Compute x = uint_max - v such that x <= int_max
84  // - Safely cast x from unsigned to signed
85  // - Map x to y such that casting y to signed leads y = v
86  value_.i = -static_cast<int64_t>(
87  std::numeric_limits<uint64_t>::max() - v) -
88  1;
89  }
90  }
91  Scalar(bool v) {
92  scalar_type_ = ScalarType::Bool;
93  value_.b = static_cast<bool>(v);
94  }
95 
96  bool IsDouble() const { return scalar_type_ == ScalarType::Double; }
97  bool IsInt64() const { return scalar_type_ == ScalarType::Int64; }
98  bool IsBool() const { return scalar_type_ == ScalarType::Bool; }
99 
102  double GetDouble() const {
103  if (!IsDouble()) {
104  utility::LogError("Scalar is not a ScalarType:Double type.");
105  }
106  return value_.d;
107  }
110  int64_t GetInt64() const {
111  if (!IsInt64()) {
112  utility::LogError("Scalar is not a ScalarType:Int64 type.");
113  }
114  return value_.i;
115  }
118  bool GetBool() const {
119  if (!IsBool()) {
120  utility::LogError("Scalar is not a ScalarType:Bool type.");
121  }
122  return value_.b;
123  }
124 
126  template <typename T>
127  T To() const {
128  if (scalar_type_ == ScalarType::Double) {
129  return static_cast<T>(value_.d);
130  } else if (scalar_type_ == ScalarType::Int64) {
131  return static_cast<T>(value_.i);
132  } else if (scalar_type_ == ScalarType::Bool) {
133  return static_cast<T>(value_.b);
134  } else {
135  utility::LogError("To: ScalarType not supported.");
136  }
137  }
138 
140  const std::string& error_msg) const {
141  if (scalar_type_ != other.scalar_type_) {
142  if (error_msg.empty()) {
143  utility::LogError("Scalar mode {} are not the same as {}.",
144  ToString(), other.ToString());
145  } else {
146  utility::LogError("Scalar mode {} are not the same as {}: {}",
147  ToString(), other.ToString(), error_msg);
148  }
149  }
150  }
151 
152  std::string ToString() const {
153  std::string scalar_type_str;
154  std::string value_str;
155  if (scalar_type_ == ScalarType::Double) {
156  scalar_type_str = "Double";
157  value_str = std::to_string(value_.d);
158  } else if (scalar_type_ == ScalarType::Int64) {
159  scalar_type_str = "Int64";
160  value_str = std::to_string(value_.i);
161  } else if (scalar_type_ == ScalarType::Bool) {
162  scalar_type_str = "Bool";
163  value_str = value_.b ? "true" : "false";
164  } else {
165  utility::LogError("ScalarTypeToString: ScalarType not supported.");
166  }
167  return scalar_type_str + ":" + value_str;
168  }
169 
170  template <typename T>
171  bool Equal(T value) const {
172  if (scalar_type_ == ScalarType::Double) {
173  return value_.d == value;
174  } else if (scalar_type_ == ScalarType::Int64) {
175  return value_.i == value;
176  } else if (scalar_type_ == ScalarType::Bool) {
177  return false; // Boolean does not equal to non-boolean values.
178  } else {
179  utility::LogError("Equals: ScalarType not supported.");
180  }
181  }
182 
183  bool Equal(bool value) const {
184  return scalar_type_ == ScalarType::Bool && value_.b == value;
185  }
186 
187  bool Equal(Scalar other) const {
188  if (other.scalar_type_ == ScalarType::Double) {
189  return Equal(other.GetDouble());
190  } else if (other.scalar_type_ == ScalarType::Int64) {
191  return Equal(other.GetInt64());
192  } else if (other.scalar_type_ == ScalarType::Bool) {
193  return scalar_type_ == ScalarType::Bool &&
194  value_.b == other.value_.b;
195  } else {
196  utility::LogError("Equals: ScalarType not supported.");
197  }
198  }
199 
200 private:
201  ScalarType scalar_type_;
202  union value_t {
203  double d;
204  int64_t i;
205  bool b;
206  } value_;
207 };
208 
209 } // namespace core
210 } // namespace open3d
#define LogError(...)
Definition: Logging.h:48
Definition: Scalar.h:23
bool IsInt64() const
Definition: Scalar.h:97
bool GetBool() const
Definition: Scalar.h:118
Scalar(double v)
Definition: Scalar.h:31
Scalar(int32_t v)
Definition: Scalar.h:43
int64_t GetInt64() const
Definition: Scalar.h:110
bool IsBool() const
Definition: Scalar.h:98
Scalar(int64_t v)
Definition: Scalar.h:47
Scalar(int16_t v)
Definition: Scalar.h:39
Scalar(bool v)
Definition: Scalar.h:91
bool Equal(bool value) const
Definition: Scalar.h:183
Scalar(float v)
Definition: Scalar.h:27
Scalar(long v, typename std::enable_if<!std::is_same< T, long >::value >::type *=0)
Definition: Scalar.h:58
Scalar(uint32_t v)
Definition: Scalar.h:71
ScalarType
Definition: Scalar.h:25
bool Equal(T value) const
Definition: Scalar.h:171
void AssertSameScalarType(Scalar other, const std::string &error_msg) const
Definition: Scalar.h:139
double GetDouble() const
Definition: Scalar.h:102
bool IsDouble() const
Definition: Scalar.h:96
Scalar(uint16_t v)
Definition: Scalar.h:67
T To() const
To<T>() does not check for scalar type and overflows.
Definition: Scalar.h:127
Scalar(uint8_t v)
Definition: Scalar.h:63
Scalar(uint64_t v)
Definition: Scalar.h:75
Scalar(int8_t v)
Definition: Scalar.h:35
std::string ToString() const
Definition: Scalar.h:152
bool Equal(Scalar other) const
Definition: Scalar.h:187
char type
Definition: FilePCD.cpp:41
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:548
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:343
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:395
Definition: PinholeCameraIntrinsic.cpp:16