blob: 16c3f6d441dc8676bafd2940380b3009f59d58e8 [file] [log] [blame]
Viet-Hoa Dobd4f6b92023-05-30 09:34:32 +01001/*
2 * Copyright (c) 2023 Arm Limited.
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
Viet-Hoa Doce3c48c2023-07-03 13:44:43 +010025#ifndef CKW_PROTOTYPE_INCLUDE_CKW_SCALARVALUE_H
26#define CKW_PROTOTYPE_INCLUDE_CKW_SCALARVALUE_H
Viet-Hoa Dobd4f6b92023-05-30 09:34:32 +010027
28#include "ckw/Error.h"
29
30#include <cstdint>
31
32namespace ckw
33{
34
35/** The scalar value known at compile-time. */
36class ScalarValue
37{
38public:
39 /** Initialize a new instance of @ref ScalarValue class with integer value 0. */
40 ScalarValue()
41 {
42 _type = Type::INT;
43 _value.i64 = 0;
44 }
45
46 /** Initialize a new instance of @ref ScalarValue class with the specified value. */
47 template <typename T>
48 ScalarValue(T value)
49 {
50 set(value);
51 }
52
53 /** Set the value. */
54 template <typename T>
55 void set(T value)
56 {
57 CKW_ASSERT(::std::is_integral<T>::value || ::std::is_floating_point<T>::value);
58 CKW_ASSERT(sizeof(T) <= 8);
59
60 _size = sizeof(T);
61
62 if(::std::is_integral<T>::value)
63 {
64 if(::std::is_signed<T>::value)
65 {
66 _type = Type::INT;
67 _value.i64 = value;
68 }
69 else
70 {
71 _type = Type::UINT;
72 _value.u64 = value;
73 }
74 }
75 else
76 {
77 _type = Type::FLOAT;
78 _value.f64 = value;
79 }
80 }
81
82 /** Get the value.
83 *
84 * The caller must make sure that what has been stored in the object must fit
85 * the output data type without data corruption or loss of accuracy.
86 */
87 template <typename T>
88 T get() const
89 {
90 CKW_ASSERT(::std::is_integral<T>::value || ::std::is_floating_point<T>::value);
91 CKW_ASSERT(sizeof(T) >= _size);
92
93 if(::std::is_integral<T>::value)
94 {
95 if(::std::is_signed<T>::value)
96 {
97 CKW_ASSERT(_type == Type::INT || _type == Type::UINT);
98 CKW_ASSERT_IF(_type == Type::UINT, sizeof(T) > _size);
99
100 return _value.i64;
101 }
102 else
103 {
104 CKW_ASSERT(_type == Type::INT);
105
106 return _value.u64;
107 }
108 }
109 else
110 {
111 return _value.f64;
112 }
113 }
114
115private:
116 union Value
117 {
118 int64_t i64;
119 uint64_t u64;
120 double f64;
121 };
122
123 enum class Type : int32_t
124 {
125 UINT,
126 INT,
127 FLOAT,
128 };
129
130 Value _value{};
131 Type _type{};
132 uint32_t _size{};
133};
134
135} // namespace ckw
136
Viet-Hoa Doce3c48c2023-07-03 13:44:43 +0100137#endif // CKW_PROTOTYPE_INCLUDE_CKW_SCALARVALUE_H