Open3D (C++ API)  0.16.1
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"
35
36namespace open3d {
37namespace core {
38
42class Scalar {
43public:
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
219private:
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
#define LogError(...)
Definition: Logging.h:67
Definition: Scalar.h:42
bool IsInt64() const
Definition: Scalar.h:116
bool GetBool() const
Definition: Scalar.h:137
Scalar(double v)
Definition: Scalar.h:50
Scalar(int32_t v)
Definition: Scalar.h:62
int64_t GetInt64() const
Definition: Scalar.h:129
bool IsBool() const
Definition: Scalar.h:117
Scalar(int64_t v)
Definition: Scalar.h:66
Scalar(int16_t v)
Definition: Scalar.h:58
Scalar(bool v)
Definition: Scalar.h:110
bool Equal(bool value) const
Definition: Scalar.h:202
Scalar(float v)
Definition: Scalar.h:46
Scalar(long v, typename std::enable_if<!std::is_same< T, long >::value >::type *=0)
Definition: Scalar.h:77
Scalar(uint32_t v)
Definition: Scalar.h:90
ScalarType
Definition: Scalar.h:44
bool Equal(T value) const
Definition: Scalar.h:190
void AssertSameScalarType(Scalar other, const std::string &error_msg) const
Definition: Scalar.h:158
double GetDouble() const
Definition: Scalar.h:121
bool IsDouble() const
Definition: Scalar.h:115
Scalar(uint16_t v)
Definition: Scalar.h:86
T To() const
To<T>() does not check for scalar type and overflows.
Definition: Scalar.h:146
Scalar(uint8_t v)
Definition: Scalar.h:82
Scalar(uint64_t v)
Definition: Scalar.h:94
Scalar(int8_t v)
Definition: Scalar.h:54
std::string ToString() const
Definition: Scalar.h:171
bool Equal(Scalar other) const
Definition: Scalar.h:206
char type
Definition: FilePCD.cpp:60
const Dtype Int64
Definition: Dtype.cpp:66
const Dtype Bool
Definition: Dtype.cpp:71
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:567
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:362
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:414
Definition: PinholeCameraIntrinsic.cpp:35