|
|
@ -22,26 +22,6 @@
|
|
|
|
#include "srslte/common/choice_type.h"
|
|
|
|
#include "srslte/common/choice_type.h"
|
|
|
|
#include "srslte/common/test_common.h"
|
|
|
|
#include "srslte/common/test_common.h"
|
|
|
|
|
|
|
|
|
|
|
|
namespace srslte {
|
|
|
|
|
|
|
|
namespace choice_details {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static_assert(static_max<1, 2>::value == 2, "StaticMax not working");
|
|
|
|
|
|
|
|
static_assert(static_max<2, 1>::value == 2, "StaticMax not working");
|
|
|
|
|
|
|
|
static_assert(type_indexer<double, char, float, int, long, double>::index == 0, "Type indexer not working");
|
|
|
|
|
|
|
|
static_assert(type_indexer<double, double, float, int, long, char>::index == 4, "Type indexer not working");
|
|
|
|
|
|
|
|
static_assert(type_indexer<double, char, float, int>::index == invalid_idx, "Type Indexer not working");
|
|
|
|
|
|
|
|
static_assert(sizeof(choice_storage_t<5, 4>) == 8, "Size of storage wrongly computed");
|
|
|
|
|
|
|
|
static_assert(alignof(choice_storage_t<5, 4>) == 4, "Alignment of storage wrongly computed");
|
|
|
|
|
|
|
|
static_assert(std::is_same<typename type_get<0, char, float, int, long, double>::type, double>::value,
|
|
|
|
|
|
|
|
"type index-based search not working");
|
|
|
|
|
|
|
|
static_assert(std::is_same<typename type_get<3, char, float, int, long, double>::type, float>::value,
|
|
|
|
|
|
|
|
"type index-based search not working");
|
|
|
|
|
|
|
|
static_assert(std::is_same<tagged_union_t<char, int, double>::default_type, char>::value,
|
|
|
|
|
|
|
|
"Default type is incorrect\n");
|
|
|
|
|
|
|
|
static_assert(tagged_union_t<char, int, double>::can_hold_type<int>(), "Can hold type implementation is incorrect\n");
|
|
|
|
|
|
|
|
static_assert(not tagged_union_t<char, int, double>::can_hold_type<uint8_t>(),
|
|
|
|
|
|
|
|
"Can hold type implementation is incorrect\n");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct C {
|
|
|
|
struct C {
|
|
|
|
static int counter;
|
|
|
|
static int counter;
|
|
|
|
C() { counter++; }
|
|
|
|
C() { counter++; }
|
|
|
@ -78,8 +58,32 @@ struct D {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
int D::counter = 0;
|
|
|
|
int D::counter = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace srslte {
|
|
|
|
|
|
|
|
namespace choice_details {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static_assert(static_max<1, 2>::value == 2, "StaticMax not working");
|
|
|
|
|
|
|
|
static_assert(static_max<2, 1>::value == 2, "StaticMax not working");
|
|
|
|
|
|
|
|
static_assert(type_indexer<double, char, float, int, long, double>::index == 0, "Type indexer not working");
|
|
|
|
|
|
|
|
static_assert(type_indexer<double, double, float, int, long, char>::index == 4, "Type indexer not working");
|
|
|
|
|
|
|
|
static_assert(type_indexer<double, char, float, int>::index == invalid_idx, "Type Indexer not working");
|
|
|
|
|
|
|
|
static_assert(sizeof(choice_storage_t<5, 4>) == 8, "Size of storage wrongly computed");
|
|
|
|
|
|
|
|
static_assert(alignof(choice_storage_t<5, 4>) == 4, "Alignment of storage wrongly computed");
|
|
|
|
|
|
|
|
static_assert(std::is_same<typename type_get<0, char, float, int, long, double>::type, double>::value,
|
|
|
|
|
|
|
|
"type index-based search not working");
|
|
|
|
|
|
|
|
static_assert(std::is_same<typename type_get<3, char, float, int, long, double>::type, float>::value,
|
|
|
|
|
|
|
|
"type index-based search not working");
|
|
|
|
|
|
|
|
static_assert(std::is_same<tagged_union_t<char, int, double>::default_type, char>::value,
|
|
|
|
|
|
|
|
"Default type is incorrect\n");
|
|
|
|
|
|
|
|
static_assert(tagged_union_t<char, int, double>::can_hold_type<int>(), "Can hold type implementation is incorrect\n");
|
|
|
|
|
|
|
|
static_assert(not tagged_union_t<char, int, double>::can_hold_type<uint8_t>(),
|
|
|
|
|
|
|
|
"Can hold type implementation is incorrect\n");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace choice_details
|
|
|
|
|
|
|
|
} // namespace srslte
|
|
|
|
|
|
|
|
|
|
|
|
int test_tagged_union()
|
|
|
|
int test_tagged_union()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
using srslte::choice_details::tagged_union_t;
|
|
|
|
tagged_union_t<char, int, double, C> u;
|
|
|
|
tagged_union_t<char, int, double, C> u;
|
|
|
|
u.construct_unsafe(5);
|
|
|
|
u.construct_unsafe(5);
|
|
|
|
TESTASSERT(u.is<int>());
|
|
|
|
TESTASSERT(u.is<int>());
|
|
|
@ -98,6 +102,9 @@ int test_tagged_union()
|
|
|
|
|
|
|
|
|
|
|
|
int test_choice()
|
|
|
|
int test_choice()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
using srslte::choice_t;
|
|
|
|
|
|
|
|
using srslte::choice_details::bad_choice_access;
|
|
|
|
|
|
|
|
|
|
|
|
TESTASSERT(C::counter == 0);
|
|
|
|
TESTASSERT(C::counter == 0);
|
|
|
|
TESTASSERT(D::counter == 0);
|
|
|
|
TESTASSERT(D::counter == 0);
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -118,7 +125,7 @@ int test_choice()
|
|
|
|
char n = '1';
|
|
|
|
char n = '1';
|
|
|
|
n = c2.get<char>();
|
|
|
|
n = c2.get<char>();
|
|
|
|
TESTASSERT(n == '1');
|
|
|
|
TESTASSERT(n == '1');
|
|
|
|
} catch (choice_details::bad_choice_access& e) {
|
|
|
|
} catch (bad_choice_access& e) {
|
|
|
|
catched = true;
|
|
|
|
catched = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
TESTASSERT(catched);
|
|
|
|
TESTASSERT(catched);
|
|
|
@ -152,10 +159,26 @@ int test_choice()
|
|
|
|
TESTASSERT(C::counter == 1);
|
|
|
|
TESTASSERT(C::counter == 1);
|
|
|
|
TESTASSERT(D::counter == 1);
|
|
|
|
TESTASSERT(D::counter == 1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TEST: Move ctor
|
|
|
|
choice_t<char, int, double, C, D> c5{std::move(c3)};
|
|
|
|
choice_t<char, int, double, C, D> c5{std::move(c3)};
|
|
|
|
TESTASSERT(C::counter == 2);
|
|
|
|
TESTASSERT(C::counter == 2);
|
|
|
|
choice_t<char, int, double, C, D> c6{std::move(c4)};
|
|
|
|
choice_t<char, int, double, C, D> c6{std::move(c4)};
|
|
|
|
TESTASSERT(D::counter == 2);
|
|
|
|
TESTASSERT(D::counter == 2);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TEST: move assignment
|
|
|
|
|
|
|
|
c = std::move(c3);
|
|
|
|
|
|
|
|
TESTASSERT(c.is<C>());
|
|
|
|
|
|
|
|
TESTASSERT(c3.is<C>() and c.holds_same_type(c3)); // move is not destructive
|
|
|
|
|
|
|
|
TESTASSERT(C::counter == 3);
|
|
|
|
|
|
|
|
c = std::move(c4);
|
|
|
|
|
|
|
|
TESTASSERT(c.is<D>());
|
|
|
|
|
|
|
|
TESTASSERT(c4.is<D>() and c.holds_same_type(c4));
|
|
|
|
|
|
|
|
TESTASSERT(C::counter == 2);
|
|
|
|
|
|
|
|
TESTASSERT(D::counter == 3);
|
|
|
|
|
|
|
|
c = std::move(c2);
|
|
|
|
|
|
|
|
TESTASSERT(c.is<double>() and c2.is<double>() and c.holds_same_type(c2));
|
|
|
|
|
|
|
|
TESTASSERT(c.get<double>() == c2.get<double>());
|
|
|
|
|
|
|
|
TESTASSERT(C::counter == 2 and D::counter == 2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
TESTASSERT(C::counter == 0);
|
|
|
|
TESTASSERT(C::counter == 0);
|
|
|
|
TESTASSERT(D::counter == 0);
|
|
|
|
TESTASSERT(D::counter == 0);
|
|
|
@ -163,11 +186,56 @@ int test_choice()
|
|
|
|
return SRSLTE_SUCCESS;
|
|
|
|
return SRSLTE_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace choice_details
|
|
|
|
struct E {
|
|
|
|
} // namespace srslte
|
|
|
|
srslte::unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*srslte::byte_buffer_pool::get_instance());
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct EVisitor {
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
|
|
|
|
void operator()(T&& t)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// do nothing
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void operator()(E& e) { pdu = std::move(e.pdu); }
|
|
|
|
|
|
|
|
srslte::unique_byte_buffer_t pdu;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int test_visit()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
using srslte::choice_t;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
choice_t<int, double, char, E> c{5};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TEST: visitor hits integer type which is noop
|
|
|
|
|
|
|
|
EVisitor v;
|
|
|
|
|
|
|
|
srslte::visit(c, v);
|
|
|
|
|
|
|
|
TESTASSERT(c.is<int>() and c.get<int>() == 5);
|
|
|
|
|
|
|
|
TESTASSERT(v.pdu == nullptr);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TEST: visitor hits type E and steals pdu
|
|
|
|
|
|
|
|
E e;
|
|
|
|
|
|
|
|
e.pdu = srslte::allocate_unique_buffer(*srslte::byte_buffer_pool::get_instance());
|
|
|
|
|
|
|
|
c = std::move(e);
|
|
|
|
|
|
|
|
TESTASSERT(c.is<E>() and c.get<E>().pdu != nullptr);
|
|
|
|
|
|
|
|
srslte::visit(c, v);
|
|
|
|
|
|
|
|
TESTASSERT(v.pdu != nullptr);
|
|
|
|
|
|
|
|
TESTASSERT(c.is<E>() and c.get<E>().pdu == nullptr);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TEST: visitor hits type E and steals pdu. Second type called there is no pdu to steal.
|
|
|
|
|
|
|
|
v.pdu = nullptr;
|
|
|
|
|
|
|
|
e.pdu = srslte::allocate_unique_buffer(*srslte::byte_buffer_pool::get_instance());
|
|
|
|
|
|
|
|
c = std::move(e);
|
|
|
|
|
|
|
|
c.visit(v);
|
|
|
|
|
|
|
|
TESTASSERT(v.pdu != nullptr);
|
|
|
|
|
|
|
|
c.visit(v);
|
|
|
|
|
|
|
|
TESTASSERT(v.pdu == nullptr);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return SRSLTE_SUCCESS;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int main()
|
|
|
|
int main()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
TESTASSERT(srslte::choice_details::test_tagged_union() == SRSLTE_SUCCESS);
|
|
|
|
TESTASSERT(test_tagged_union() == SRSLTE_SUCCESS);
|
|
|
|
TESTASSERT(srslte::choice_details::test_choice() == SRSLTE_SUCCESS);
|
|
|
|
TESTASSERT(test_choice() == SRSLTE_SUCCESS);
|
|
|
|
|
|
|
|
TESTASSERT(test_visit() == SRSLTE_SUCCESS);
|
|
|
|
}
|
|
|
|
}
|
|
|
|