Skip to content

Commit f12c60c

Browse files
authored
DPL Analysis: add unsigned int types to Variant/Configurable (#6577)
* add unsigned int types to Variant * add handling and tests for uints
1 parent 6d593ff commit f12c60c

12 files changed

Lines changed: 212 additions & 27 deletions

Framework/Core/include/Framework/ConfigParamRegistry.h

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,24 @@
2121
#include <string>
2222
#include <cassert>
2323

24+
namespace
25+
{
26+
template <typename T>
27+
constexpr auto isSimpleType()
28+
{
29+
return std::is_same_v<T, int> ||
30+
std::is_same_v<T, uint8_t> ||
31+
std::is_same_v<T, uint16_t> ||
32+
std::is_same_v<T, uint32_t> ||
33+
std::is_same_v<T, uint64_t> ||
34+
std::is_same_v<T, int64_t> ||
35+
std::is_same_v<T, long> ||
36+
std::is_same_v<T, float> ||
37+
std::is_same_v<T, double> ||
38+
std::is_same_v<T, bool>;
39+
}
40+
} // namespace
41+
2442
namespace o2::framework
2543
{
2644
class ConfigParamStore;
@@ -54,12 +72,7 @@ class ConfigParamRegistry
5472
{
5573
assert(mStore.get());
5674
try {
57-
if constexpr (std::is_same_v<T, int> ||
58-
std::is_same_v<T, int64_t> ||
59-
std::is_same_v<T, long> ||
60-
std::is_same_v<T, float> ||
61-
std::is_same_v<T, double> ||
62-
std::is_same_v<T, bool>) {
75+
if constexpr (isSimpleType<T>()) {
6376
return mStore->store().get<T>(key);
6477
} else if constexpr (std::is_same_v<T, std::string>) {
6578
return mStore->store().get<std::string>(key);

Framework/Core/include/Framework/ConfigParamsHelper.h

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,7 @@ struct ConfigParamsHelper {
105105
const char* name = spec.name.c_str();
106106
const char* help = spec.help.c_str();
107107

108-
if constexpr (V == VariantType::Int ||
109-
V == VariantType::Int64 ||
110-
V == VariantType::Float ||
111-
V == VariantType::Double ||
112-
V == VariantType::Bool) {
108+
if constexpr (isSimpleVariant<V>()) {
113109
using Type = typename variant_type<V>::type;
114110
using BoostType = typename std::conditional<V == VariantType::String, std::string, Type>::type;
115111
auto value = boost::program_options::value<BoostType>();
@@ -120,14 +116,7 @@ struct ConfigParamsHelper {
120116
value = value->zero_tokens();
121117
}
122118
options.add_options()(name, value, help);
123-
} else if constexpr (V == VariantType::ArrayInt ||
124-
V == VariantType::ArrayFloat ||
125-
V == VariantType::ArrayDouble ||
126-
V == VariantType::ArrayBool ||
127-
V == VariantType::ArrayString ||
128-
V == VariantType::Array2DInt ||
129-
V == VariantType::Array2DFloat ||
130-
V == VariantType::Array2DDouble) {
119+
} else if constexpr (isArray<V>() || isArray2D<V>()) {
131120
auto value = boost::program_options::value<std::string>();
132121
value = value->default_value(spec.defaultValue.asString());
133122
if constexpr (V != VariantType::String) {

Framework/Core/include/Framework/Variant.h

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ namespace o2::framework
2828

2929
enum class VariantType : int { Int = 0,
3030
Int64,
31+
UInt8,
32+
UInt16,
33+
UInt32,
34+
UInt64,
3135
Float,
3236
Double,
3337
String,
@@ -49,19 +53,41 @@ enum class VariantType : int { Int = 0,
4953
template <VariantType V>
5054
constexpr auto isArray()
5155
{
52-
return (V == VariantType::ArrayBool || V == VariantType::ArrayDouble || V == VariantType::ArrayFloat || V == VariantType::ArrayInt || V == VariantType::ArrayString);
56+
return (V == VariantType::ArrayBool ||
57+
V == VariantType::ArrayDouble ||
58+
V == VariantType::ArrayFloat ||
59+
V == VariantType::ArrayInt ||
60+
V == VariantType::ArrayString);
5361
}
5462

5563
template <VariantType V>
5664
constexpr auto isArray2D()
5765
{
58-
return (V == VariantType::Array2DInt || V == VariantType::Array2DFloat || V == VariantType::Array2DDouble);
66+
return (V == VariantType::Array2DInt ||
67+
V == VariantType::Array2DFloat ||
68+
V == VariantType::Array2DDouble);
5969
}
6070

6171
template <VariantType V>
6272
constexpr auto isLabeledArray()
6373
{
64-
return (V == VariantType::LabeledArrayInt || V == VariantType::LabeledArrayFloat || V == VariantType::LabeledArrayDouble);
74+
return (V == VariantType::LabeledArrayInt ||
75+
V == VariantType::LabeledArrayFloat ||
76+
V == VariantType::LabeledArrayDouble);
77+
}
78+
79+
template <VariantType V>
80+
constexpr auto isSimpleVariant()
81+
{
82+
return (V == VariantType::Int) ||
83+
(V == VariantType::Int64) ||
84+
(V == VariantType::UInt8) ||
85+
(V == VariantType::UInt16) ||
86+
(V == VariantType::UInt32) ||
87+
(V == VariantType::UInt64) ||
88+
(V == VariantType::Float) ||
89+
(V == VariantType::Double) ||
90+
(V == VariantType::Bool);
6591
}
6692

6793
template <typename T>
@@ -76,6 +102,11 @@ struct variant_trait : std::integral_constant<VariantType, VariantType::Unknown>
76102
DECLARE_VARIANT_TRAIT(int, Int);
77103
DECLARE_VARIANT_TRAIT(long int, Int64);
78104
DECLARE_VARIANT_TRAIT(long long int, Int64);
105+
DECLARE_VARIANT_TRAIT(uint8_t, UInt8);
106+
DECLARE_VARIANT_TRAIT(uint16_t, UInt16);
107+
DECLARE_VARIANT_TRAIT(uint32_t, UInt32);
108+
DECLARE_VARIANT_TRAIT(uint64_t, UInt64);
109+
79110
DECLARE_VARIANT_TRAIT(float, Float);
80111
DECLARE_VARIANT_TRAIT(double, Double);
81112
DECLARE_VARIANT_TRAIT(bool, Bool);
@@ -152,6 +183,10 @@ struct variant_type {
152183

153184
DECLARE_VARIANT_TYPE(int, Int);
154185
DECLARE_VARIANT_TYPE(int64_t, Int64);
186+
DECLARE_VARIANT_TYPE(uint8_t, UInt8);
187+
DECLARE_VARIANT_TYPE(uint16_t, UInt16);
188+
DECLARE_VARIANT_TYPE(uint32_t, UInt32);
189+
DECLARE_VARIANT_TYPE(uint64_t, UInt64);
155190
DECLARE_VARIANT_TYPE(float, Float);
156191
DECLARE_VARIANT_TYPE(double, Double);
157192
DECLARE_VARIANT_TYPE(const char*, String);
@@ -236,7 +271,8 @@ struct variant_helper<S, std::string> {
236271
/// Variant for configuration parameter storage. Owns stored data.
237272
class Variant
238273
{
239-
using storage_t = std::aligned_union<8, int, int64_t, const char*, float, double, bool,
274+
using storage_t = std::aligned_union<8, int, int64_t, uint8_t, uint16_t, uint32_t, uint64_t,
275+
const char*, float, double, bool,
240276
int*, float*, double*, bool*,
241277
Array2D<int>, Array2D<float>, Array2D<double>,
242278
LabeledArray<int>, LabeledArray<float>, LabeledArray<double>>::type;
@@ -271,10 +307,10 @@ class Variant
271307
}
272308

273309
Variant(const Variant& other);
274-
Variant(Variant&& other);
310+
Variant(Variant&& other) noexcept;
275311
~Variant();
276312
Variant& operator=(const Variant& other);
277-
Variant& operator=(Variant&& other);
313+
Variant& operator=(Variant&& other) noexcept;
278314

279315
template <typename T>
280316
T get() const

Framework/Core/src/BoostOptionsRetriever.cxx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,18 @@ void BoostOptionsRetriever::update(std::vector<ConfigParamSpec> const& specs,
5050
case VariantType::Int:
5151
options = options(name, bpo::value<int>()->default_value(spec.defaultValue.get<int>()), help);
5252
break;
53+
case VariantType::UInt8:
54+
options = options(name, bpo::value<int>()->default_value(spec.defaultValue.get<uint8_t>()), help);
55+
break;
56+
case VariantType::UInt16:
57+
options = options(name, bpo::value<int>()->default_value(spec.defaultValue.get<uint16_t>()), help);
58+
break;
59+
case VariantType::UInt32:
60+
options = options(name, bpo::value<int>()->default_value(spec.defaultValue.get<uint32_t>()), help);
61+
break;
62+
case VariantType::UInt64:
63+
options = options(name, bpo::value<int>()->default_value(spec.defaultValue.get<uint64_t>()), help);
64+
break;
5365
case VariantType::Int64:
5466
options = options(name, bpo::value<int64_t>()->default_value(spec.defaultValue.get<int64_t>()), help);
5567
break;

Framework/Core/src/ConfigParamsHelper.cxx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,18 @@ void ConfigParamsHelper::populateBoostProgramOptions(
4444
case VariantType::Int64:
4545
addConfigSpecOption<VariantType::Int64>(spec, options);
4646
break;
47+
case VariantType::UInt8:
48+
addConfigSpecOption<VariantType::UInt8>(spec, options);
49+
break;
50+
case VariantType::UInt16:
51+
addConfigSpecOption<VariantType::UInt16>(spec, options);
52+
break;
53+
case VariantType::UInt32:
54+
addConfigSpecOption<VariantType::UInt32>(spec, options);
55+
break;
56+
case VariantType::UInt64:
57+
addConfigSpecOption<VariantType::UInt64>(spec, options);
58+
break;
4759
case VariantType::Float:
4860
addConfigSpecOption<VariantType::Float>(spec, options);
4961
break;

Framework/Core/src/PropertyTreeHelpers.cxx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,18 @@ void PropertyTreeHelpers::populateDefaults(std::vector<ConfigParamSpec> const& s
3636
case VariantType::Int:
3737
pt.put(key, spec.defaultValue.get<int>());
3838
break;
39+
case VariantType::UInt8:
40+
pt.put(key, spec.defaultValue.get<uint8_t>());
41+
break;
42+
case VariantType::UInt16:
43+
pt.put(key, spec.defaultValue.get<uint16_t>());
44+
break;
45+
case VariantType::UInt32:
46+
pt.put(key, spec.defaultValue.get<uint32_t>());
47+
break;
48+
case VariantType::UInt64:
49+
pt.put(key, spec.defaultValue.get<uint64_t>());
50+
break;
3951
case VariantType::Int64:
4052
pt.put(key, spec.defaultValue.get<int64_t>());
4153
break;
@@ -116,6 +128,18 @@ void PropertyTreeHelpers::populate(std::vector<ConfigParamSpec> const& schema,
116128
case VariantType::Int:
117129
pt.put(key, vmap[key].as<int>());
118130
break;
131+
case VariantType::UInt8:
132+
pt.put(key, vmap[key].as<uint8_t>());
133+
break;
134+
case VariantType::UInt16:
135+
pt.put(key, vmap[key].as<uint16_t>());
136+
break;
137+
case VariantType::UInt32:
138+
pt.put(key, vmap[key].as<uint32_t>());
139+
break;
140+
case VariantType::UInt64:
141+
pt.put(key, vmap[key].as<uint64_t>());
142+
break;
119143
case VariantType::Int64:
120144
pt.put(key, vmap[key].as<int64_t>());
121145
break;
@@ -209,6 +233,18 @@ void PropertyTreeHelpers::populate(std::vector<ConfigParamSpec> const& schema,
209233
case VariantType::Int:
210234
pt.put(key, (*it).get_value<int>());
211235
break;
236+
case VariantType::UInt8:
237+
pt.put(key, (*it).get_value<uint8_t>());
238+
break;
239+
case VariantType::UInt16:
240+
pt.put(key, (*it).get_value<uint16_t>());
241+
break;
242+
case VariantType::UInt32:
243+
pt.put(key, (*it).get_value<uint32_t>());
244+
break;
245+
case VariantType::UInt64:
246+
pt.put(key, (*it).get_value<uint64_t>());
247+
break;
212248
case VariantType::Int64:
213249
pt.put(key, (*it).get_value<int64_t>());
214250
break;

Framework/Core/src/Variant.cxx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,18 @@ std::ostream& operator<<(std::ostream& oss, Variant const& val)
5656
case VariantType::Int:
5757
oss << val.get<int>();
5858
break;
59+
case VariantType::UInt8:
60+
oss << val.get<uint8_t>();
61+
break;
62+
case VariantType::UInt16:
63+
oss << val.get<uint16_t>();
64+
break;
65+
case VariantType::UInt32:
66+
oss << val.get<uint32_t>();
67+
break;
68+
case VariantType::UInt64:
69+
oss << val.get<uint64_t>();
70+
break;
5971
case VariantType::Int64:
6072
oss << val.get<int64_t>();
6173
break;
@@ -146,7 +158,7 @@ Variant::Variant(const Variant& other) : mType(other.mType)
146158
}
147159
}
148160

149-
Variant::Variant(Variant&& other) : mType(other.mType)
161+
Variant::Variant(Variant&& other) noexcept : mType(other.mType)
150162
{
151163
mStore = other.mStore;
152164
mSize = other.mSize;
@@ -222,7 +234,7 @@ Variant& Variant::operator=(const Variant& other)
222234
}
223235
}
224236

225-
Variant& Variant::operator=(Variant&& other)
237+
Variant& Variant::operator=(Variant&& other) noexcept
226238
{
227239
mSize = other.mSize;
228240
mType = other.mType;

Framework/Core/src/WorkflowSerializationHelpers.cxx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,18 @@ struct WorkflowImporter : public rapidjson::BaseReaderHandler<rapidjson::UTF8<>,
319319
case VariantType::Int:
320320
opt = std::make_unique<ConfigParamSpec>(optionName, optionType, std::stoi(optionDefault, nullptr), HelpString{optionHelp}, optionKind);
321321
break;
322+
case VariantType::UInt8:
323+
opt = std::make_unique<ConfigParamSpec>(optionName, optionType, static_cast<uint8_t>(std::stoul(optionDefault, nullptr)), HelpString{optionHelp}, optionKind);
324+
break;
325+
case VariantType::UInt16:
326+
opt = std::make_unique<ConfigParamSpec>(optionName, optionType, static_cast<uint16_t>(std::stoul(optionDefault, nullptr)), HelpString{optionHelp}, optionKind);
327+
break;
328+
case VariantType::UInt32:
329+
opt = std::make_unique<ConfigParamSpec>(optionName, optionType, static_cast<uint32_t>(std::stoul(optionDefault, nullptr)), HelpString{optionHelp}, optionKind);
330+
break;
331+
case VariantType::UInt64:
332+
opt = std::make_unique<ConfigParamSpec>(optionName, optionType, std::stoul(optionDefault, nullptr), HelpString{optionHelp}, optionKind);
333+
break;
322334
case VariantType::Int64:
323335
opt = std::make_unique<ConfigParamSpec>(optionName, optionType, std::stol(optionDefault, nullptr), HelpString{optionHelp}, optionKind);
324336
break;

Framework/Core/test/test_BoostOptionsRetriever.cxx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ BOOST_AUTO_TEST_CASE(TrivialBoostOptionsRetrieverTest)
2929

3030
auto specs = std::vector<ConfigParamSpec>{
3131
{"someInt", VariantType::Int, 2, {"some int option"}},
32+
{"someUInt8", VariantType::UInt8, static_cast<uint8_t>(2u), {"some uint8 option"}},
33+
{"someUInt16", VariantType::UInt16, static_cast<uint16_t>(2u), {"some uint16 option"}},
34+
{"someUInt32", VariantType::UInt32, 2u, {"some uint32 option"}},
35+
{"someUInt64", VariantType::UInt64, static_cast<uint64_t>(2ul), {"some uint64 option"}},
3236
{"someInt64", VariantType::Int64, 4ll, {"some int64 option"}},
3337
{"someBool", VariantType::Bool, false, {"some bool option"}},
3438
{"someFloat", VariantType::Float, 2.0f, {"some float option"}},
@@ -38,6 +42,10 @@ BOOST_AUTO_TEST_CASE(TrivialBoostOptionsRetrieverTest)
3842
"test",
3943
"--someBool",
4044
"--someInt", "1",
45+
"--someUInt8", "1",
46+
"--someUInt16", "1",
47+
"--someUInt32", "1",
48+
"--someUInt64", "1",
4149
"--someInt64", "50000000000000",
4250
"--someFloat", "0.5",
4351
"--someDouble", "0.5",
@@ -50,6 +58,10 @@ BOOST_AUTO_TEST_CASE(TrivialBoostOptionsRetrieverTest)
5058
bpo::store(parse_command_line(sizeof(args) / sizeof(char*), args, opts), vm);
5159
bpo::notify(vm);
5260
BOOST_CHECK(vm["someInt"].as<int>() == 1);
61+
BOOST_CHECK(vm["someUInt8"].as<uint8_t>() == '1');
62+
BOOST_CHECK(vm["someUInt16"].as<uint16_t>() == 1);
63+
BOOST_CHECK(vm["someUInt32"].as<uint32_t>() == 1);
64+
BOOST_CHECK(vm["someUInt64"].as<uint64_t>() == 1);
5365
BOOST_CHECK(vm["someInt64"].as<int64_t>() == 50000000000000ll);
5466
BOOST_CHECK(vm["someBool"].as<bool>() == true);
5567
BOOST_CHECK(vm["someString"].as<std::string>() == "foobar");

Framework/Core/test/test_ConfigParamRegistry.cxx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ BOOST_AUTO_TEST_CASE(TestConfigParamRegistry)
4141
("aFloat", bpo::value<float>()->default_value(10.f)) //
4242
("aDouble", bpo::value<double>()->default_value(20.)) //
4343
("anInt", bpo::value<int>()->default_value(1)) //
44+
("anUInt8", bpo::value<uint8_t>()->default_value(1)) //
45+
("anUInt16", bpo::value<uint16_t>()->default_value(1)) //
46+
("anUInt32", bpo::value<uint32_t>()->default_value(1)) //
47+
("anUInt64", bpo::value<uint64_t>()->default_value(1)) //
4448
("anInt64", bpo::value<int64_t>()->default_value(1ll)) //
4549
("aBoolean", bpo::value<bool>()->zero_tokens()->default_value(false)) //
4650
("aString,s", bpo::value<std::string>()->default_value("something")) //
@@ -52,6 +56,10 @@ BOOST_AUTO_TEST_CASE(TestConfigParamRegistry)
5256
options->ParseAll({"cmd", "--aFloat", "1.0",
5357
"--aDouble", "2.0",
5458
"--anInt", "10",
59+
"--anUInt8", "2",
60+
"--anUInt16", "10",
61+
"--anUInt32", "10",
62+
"--anUInt64", "10",
5563
"--anInt64", "50000000000000",
5664
"--aBoolean",
5765
"-s", "somethingelse",
@@ -60,6 +68,10 @@ BOOST_AUTO_TEST_CASE(TestConfigParamRegistry)
6068
true);
6169
std::vector<ConfigParamSpec> specs{
6270
ConfigParamSpec{"anInt", VariantType::Int, 1, {"an int option"}},
71+
ConfigParamSpec{"anUInt8", VariantType::UInt8, static_cast<uint8_t>(1u), {"an uint8 option"}},
72+
ConfigParamSpec{"anUInt16", VariantType::UInt16, static_cast<uint16_t>(1u), {"an uint16 option"}},
73+
ConfigParamSpec{"anUInt32", VariantType::UInt32, 1u, {"an uint32 option"}},
74+
ConfigParamSpec{"anUInt64", VariantType::UInt64, static_cast<uint64_t>(1ul), {"an uint64 option"}},
6375
ConfigParamSpec{"anInt64", VariantType::Int64, 1ll, {"an int64_t option"}},
6476
ConfigParamSpec{"aFloat", VariantType::Float, 2.0f, {"a float option"}},
6577
ConfigParamSpec{"aDouble", VariantType::Double, 3., {"a double option"}},
@@ -82,6 +94,10 @@ BOOST_AUTO_TEST_CASE(TestConfigParamRegistry)
8294
BOOST_CHECK_EQUAL(registry.get<float>("aFloat"), 1.0);
8395
BOOST_CHECK_EQUAL(registry.get<double>("aDouble"), 2.0);
8496
BOOST_CHECK_EQUAL(registry.get<int>("anInt"), 10);
97+
BOOST_CHECK_EQUAL(registry.get<uint8_t>("anUInt8"), '2');
98+
BOOST_CHECK_EQUAL(registry.get<uint16_t>("anUInt16"), 10);
99+
BOOST_CHECK_EQUAL(registry.get<uint32_t>("anUInt32"), 10);
100+
BOOST_CHECK_EQUAL(registry.get<uint64_t>("anUInt64"), 10);
85101
BOOST_CHECK_EQUAL(registry.get<int64_t>("anInt64"), 50000000000000ll);
86102
BOOST_CHECK_EQUAL(registry.get<bool>("aBoolean"), true);
87103
BOOST_CHECK_EQUAL(registry.get<std::string>("aString"), "somethingelse");

0 commit comments

Comments
 (0)