Open3D (C++ API)  0.19.0
Loading...
Searching...
No Matches
Scalar.h
Go to the documentation of this file.
1// ----------------------------------------------------------------------------
2// - Open3D: www.open3d.org -
3// ----------------------------------------------------------------------------
4// Copyright (c) 2018-2024 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"
16
17namespace open3d {
18namespace core {
19
23class Scalar {
24public:
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 }
43 Scalar(int32_t v) {
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 }
71 Scalar(uint32_t v) {
72 scalar_type_ = ScalarType::Int64;
73 value_.i = static_cast<int64_t>(v);
74 }
75 Scalar(uint64_t v) {
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
200private:
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
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
Definition PinholeCameraIntrinsic.cpp:16