Skip to content

Commit

Permalink
DataFormats: add operator< to DataDescription and DataOrigin
Browse files Browse the repository at this point in the history
This is needed in case we want to sort them.
  • Loading branch information
ktf committed Oct 15, 2018
1 parent 99e99e7 commit d4557ac
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 1 deletion.
16 changes: 16 additions & 0 deletions DataFormats/Headers/include/Headers/DataHeader.h
Expand Up @@ -205,20 +205,35 @@ struct DescriptorCompareTraits {
static bool compare(const T &lh, const T &rh, Length N) {
return std::memcmp(lh.str, rh.str, N) == 0;
}
template <typename T, typename Length>
static bool lessThen(const T& lh, const T& rh, Length N)
{
return std::memcmp(lh.str, rh.str, N) < 0;
}
};
template<>
struct DescriptorCompareTraits<1> {
template<typename T, typename Length>
static bool compare(const T &lh, const T &rh, Length) {
return lh.itg[0] == rh.itg[0];
}
template <typename T, typename Length>
static bool lessThen(const T& lh, const T& rh, Length)
{
return lh.itg[0] < rh.itg[0];
}
};
template<>
struct DescriptorCompareTraits<2> {
template<typename T, typename Length>
static bool compare(const T &lh, const T &rh, Length) {
return (lh.itg[0] == rh.itg[0]) && (lh.itg[1] == rh.itg[1]);
}
template <typename T, typename Length>
static bool lessThen(const T& lh, const T& rh, Length)
{
return std::tie(lh.itg[0], lh.itg[1]) < std::tie(rh.itg[0], rh.itg[1]);
}
};

//__________________________________________________________________________________________________
Expand Down Expand Up @@ -293,6 +308,7 @@ struct Descriptor {
}

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

// explicitly forbid comparison with e.g. const char* strings
Expand Down
51 changes: 50 additions & 1 deletion DataFormats/Headers/test/testDataHeader.cxx
Expand Up @@ -132,6 +132,11 @@ namespace o2 {
BOOST_CHECK(desc.as<std::string>().length() == 6);
BOOST_CHECK(runtimeDesc.as<std::string>().length() == 16);
BOOST_CHECK(DataDescription("INVALIDDATA").as<std::string>().length() == 11);

BOOST_CHECK(DataDescription("A") < DataDescription("B"));
BOOST_CHECK(DataDescription("AA") < DataDescription("AB"));
BOOST_CHECK(DataDescription("AAA") < DataDescription("AAB"));
BOOST_CHECK(DataDescription("AAA") < DataDescription("ABA"));
}

BOOST_AUTO_TEST_CASE(DataOrigin_test)
Expand All @@ -141,12 +146,56 @@ namespace o2 {
using TestDescriptorT = Descriptor<descriptorSize>;
BOOST_CHECK(TestDescriptorT::size == descriptorSize);
BOOST_CHECK(TestDescriptorT::bitcount == descriptorSize * 8);
BOOST_CHECK(sizeof(TestDescriptorT::ItgType)*TestDescriptorT::arraySize == descriptorSize);
BOOST_CHECK(sizeof(TestDescriptorT::ItgType) * TestDescriptorT::arraySize == descriptorSize);
BOOST_CHECK(TestDescriptorT::size == sizeof(DataOrigin));

// we want to explicitely have the size of DataOrigin to be 4
static_assert(sizeof(DataOrigin) == 4,
"DataOrigin struct must be of size 4");

// Check that ordering works.
BOOST_CHECK(DataOrigin("A") < DataOrigin("B"));
BOOST_CHECK(DataOrigin("AA") < DataOrigin("AB"));
BOOST_CHECK(DataOrigin("AAA") < DataOrigin("AAB"));
BOOST_CHECK(DataOrigin("AAA") < DataOrigin("ABA"));
std::vector<DataOrigin> v1 = { DataOrigin("B"), DataOrigin("C"), DataOrigin("A") };
std::sort(v1.begin(), v1.end());
BOOST_CHECK_EQUAL(v1[0], DataOrigin("A"));
BOOST_CHECK_EQUAL(v1[1], DataOrigin("B"));
BOOST_CHECK_EQUAL(v1[2], DataOrigin("C"));
std::vector<DataOrigin> v2 = { DataOrigin("A"), DataOrigin("B") };
std::sort(v2.begin(), v2.end());
BOOST_CHECK_EQUAL(v2[0], DataOrigin("A"));
BOOST_CHECK_EQUAL(v2[1], DataOrigin("B"));

using CustomHeader = std::tuple<DataOrigin, DataDescription>;
std::vector<CustomHeader> v3{ CustomHeader{ "TST", "B" }, CustomHeader{ "TST", "A" } };
std::sort(v3.begin(), v3.end());
auto h0 = CustomHeader{ "TST", "A" };
auto h1 = CustomHeader{ "TST", "B" };
BOOST_CHECK(v3[0] == h0);
BOOST_CHECK(v3[1] == h1);

using CustomHeader2 = std::tuple<DataOrigin, DataDescription, int>;
std::vector<CustomHeader2> v4{ CustomHeader2{ "TST", "A", 1 }, CustomHeader2{ "TST", "A", 0 } };
std::sort(v4.begin(), v4.end());
auto hh0 = CustomHeader2{ "TST", "A", 0 };
auto hh1 = CustomHeader2{ "TST", "A", 1 };
BOOST_CHECK(v4[0] == hh0);
BOOST_CHECK(v4[1] == hh1);

struct CustomHeader3 {
DataOrigin origin;
DataDescription desc;
uint64_t subSpec;
int isOut;
};
std::vector<CustomHeader3> v5{ CustomHeader3{ "TST", "A", 0, 1 }, CustomHeader3{ "TST", "A", 0, 0 } };
std::sort(v5.begin(), v5.end(), [](CustomHeader3 const& lhs, CustomHeader3 const& rhs) {
return std::tie(lhs.origin, lhs.desc, rhs.subSpec, lhs.isOut) < std::tie(rhs.origin, rhs.desc, rhs.subSpec, rhs.isOut);
});
BOOST_CHECK(v5[0].isOut == 0);
BOOST_CHECK(v5[1].isOut == 1);
}

BOOST_AUTO_TEST_CASE(BaseHeader_test)
Expand Down

0 comments on commit d4557ac

Please sign in to comment.