Skip to content

Commit d4557ac

Browse files
committed
DataFormats: add operator< to DataDescription and DataOrigin
This is needed in case we want to sort them.
1 parent 99e99e7 commit d4557ac

File tree

2 files changed

+66
-1
lines changed

2 files changed

+66
-1
lines changed

DataFormats/Headers/include/Headers/DataHeader.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,20 +205,35 @@ struct DescriptorCompareTraits {
205205
static bool compare(const T &lh, const T &rh, Length N) {
206206
return std::memcmp(lh.str, rh.str, N) == 0;
207207
}
208+
template <typename T, typename Length>
209+
static bool lessThen(const T& lh, const T& rh, Length N)
210+
{
211+
return std::memcmp(lh.str, rh.str, N) < 0;
212+
}
208213
};
209214
template<>
210215
struct DescriptorCompareTraits<1> {
211216
template<typename T, typename Length>
212217
static bool compare(const T &lh, const T &rh, Length) {
213218
return lh.itg[0] == rh.itg[0];
214219
}
220+
template <typename T, typename Length>
221+
static bool lessThen(const T& lh, const T& rh, Length)
222+
{
223+
return lh.itg[0] < rh.itg[0];
224+
}
215225
};
216226
template<>
217227
struct DescriptorCompareTraits<2> {
218228
template<typename T, typename Length>
219229
static bool compare(const T &lh, const T &rh, Length) {
220230
return (lh.itg[0] == rh.itg[0]) && (lh.itg[1] == rh.itg[1]);
221231
}
232+
template <typename T, typename Length>
233+
static bool lessThen(const T& lh, const T& rh, Length)
234+
{
235+
return std::tie(lh.itg[0], lh.itg[1]) < std::tie(rh.itg[0], rh.itg[1]);
236+
}
222237
};
223238

224239
//__________________________________________________________________________________________________
@@ -293,6 +308,7 @@ struct Descriptor {
293308
}
294309

295310
bool operator==(const Descriptor& other) const {return DescriptorCompareTraits<arraySize>::compare(*this,other, N);}
311+
bool operator<(const Descriptor& other) const { return DescriptorCompareTraits<arraySize>::lessThen(*this, other, N); }
296312
bool operator!=(const Descriptor& other) const {return not this->operator==(other);}
297313

298314
// explicitly forbid comparison with e.g. const char* strings

DataFormats/Headers/test/testDataHeader.cxx

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,11 @@ namespace o2 {
132132
BOOST_CHECK(desc.as<std::string>().length() == 6);
133133
BOOST_CHECK(runtimeDesc.as<std::string>().length() == 16);
134134
BOOST_CHECK(DataDescription("INVALIDDATA").as<std::string>().length() == 11);
135+
136+
BOOST_CHECK(DataDescription("A") < DataDescription("B"));
137+
BOOST_CHECK(DataDescription("AA") < DataDescription("AB"));
138+
BOOST_CHECK(DataDescription("AAA") < DataDescription("AAB"));
139+
BOOST_CHECK(DataDescription("AAA") < DataDescription("ABA"));
135140
}
136141

137142
BOOST_AUTO_TEST_CASE(DataOrigin_test)
@@ -141,12 +146,56 @@ namespace o2 {
141146
using TestDescriptorT = Descriptor<descriptorSize>;
142147
BOOST_CHECK(TestDescriptorT::size == descriptorSize);
143148
BOOST_CHECK(TestDescriptorT::bitcount == descriptorSize * 8);
144-
BOOST_CHECK(sizeof(TestDescriptorT::ItgType)*TestDescriptorT::arraySize == descriptorSize);
149+
BOOST_CHECK(sizeof(TestDescriptorT::ItgType) * TestDescriptorT::arraySize == descriptorSize);
145150
BOOST_CHECK(TestDescriptorT::size == sizeof(DataOrigin));
146151

147152
// we want to explicitely have the size of DataOrigin to be 4
148153
static_assert(sizeof(DataOrigin) == 4,
149154
"DataOrigin struct must be of size 4");
155+
156+
// Check that ordering works.
157+
BOOST_CHECK(DataOrigin("A") < DataOrigin("B"));
158+
BOOST_CHECK(DataOrigin("AA") < DataOrigin("AB"));
159+
BOOST_CHECK(DataOrigin("AAA") < DataOrigin("AAB"));
160+
BOOST_CHECK(DataOrigin("AAA") < DataOrigin("ABA"));
161+
std::vector<DataOrigin> v1 = { DataOrigin("B"), DataOrigin("C"), DataOrigin("A") };
162+
std::sort(v1.begin(), v1.end());
163+
BOOST_CHECK_EQUAL(v1[0], DataOrigin("A"));
164+
BOOST_CHECK_EQUAL(v1[1], DataOrigin("B"));
165+
BOOST_CHECK_EQUAL(v1[2], DataOrigin("C"));
166+
std::vector<DataOrigin> v2 = { DataOrigin("A"), DataOrigin("B") };
167+
std::sort(v2.begin(), v2.end());
168+
BOOST_CHECK_EQUAL(v2[0], DataOrigin("A"));
169+
BOOST_CHECK_EQUAL(v2[1], DataOrigin("B"));
170+
171+
using CustomHeader = std::tuple<DataOrigin, DataDescription>;
172+
std::vector<CustomHeader> v3{ CustomHeader{ "TST", "B" }, CustomHeader{ "TST", "A" } };
173+
std::sort(v3.begin(), v3.end());
174+
auto h0 = CustomHeader{ "TST", "A" };
175+
auto h1 = CustomHeader{ "TST", "B" };
176+
BOOST_CHECK(v3[0] == h0);
177+
BOOST_CHECK(v3[1] == h1);
178+
179+
using CustomHeader2 = std::tuple<DataOrigin, DataDescription, int>;
180+
std::vector<CustomHeader2> v4{ CustomHeader2{ "TST", "A", 1 }, CustomHeader2{ "TST", "A", 0 } };
181+
std::sort(v4.begin(), v4.end());
182+
auto hh0 = CustomHeader2{ "TST", "A", 0 };
183+
auto hh1 = CustomHeader2{ "TST", "A", 1 };
184+
BOOST_CHECK(v4[0] == hh0);
185+
BOOST_CHECK(v4[1] == hh1);
186+
187+
struct CustomHeader3 {
188+
DataOrigin origin;
189+
DataDescription desc;
190+
uint64_t subSpec;
191+
int isOut;
192+
};
193+
std::vector<CustomHeader3> v5{ CustomHeader3{ "TST", "A", 0, 1 }, CustomHeader3{ "TST", "A", 0, 0 } };
194+
std::sort(v5.begin(), v5.end(), [](CustomHeader3 const& lhs, CustomHeader3 const& rhs) {
195+
return std::tie(lhs.origin, lhs.desc, rhs.subSpec, lhs.isOut) < std::tie(rhs.origin, rhs.desc, rhs.subSpec, rhs.isOut);
196+
});
197+
BOOST_CHECK(v5[0].isOut == 0);
198+
BOOST_CHECK(v5[1].isOut == 1);
150199
}
151200

152201
BOOST_AUTO_TEST_CASE(BaseHeader_test)

0 commit comments

Comments
 (0)