refactor - increase code reuse in adt files

master
Francisco 4 years ago committed by Francisco Paisana
parent 5eccfad05b
commit d04a19f8bc

@ -1,52 +0,0 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2021 Software Radio Systems Limited
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the distribution.
*
*/
#ifndef SRSRAN_ADT_UTILS_H
#define SRSRAN_ADT_UTILS_H
#ifdef __EXCEPTIONS
#include <stdexcept>
#define EXCEPTIONS_ENABLED 1
namespace srsran {
class bad_type_access : public std::runtime_error
{
public:
explicit bad_type_access(const std::string& what_arg) : runtime_error(what_arg) {}
explicit bad_type_access(const char* what_arg) : runtime_error(what_arg) {}
};
#define THROW_BAD_ACCESS(msg) throw bad_type_access(msg)
} // namespace srsran
#else
#define EXCEPTIONS_ENABLED 0
#include <cstdio>
#include <cstdlib>
namespace srsran {
#define THROW_BAD_ACCESS(msg) \
std::fprintf(stderr, "ERROR: exception thrown with %s", msg); \
std::abort()
} // namespace srsran
#endif
#endif // SRSRAN_ADT_UTILS_H

@ -13,7 +13,7 @@
#ifndef SRSRAN_DYN_BITSET_H #ifndef SRSRAN_DYN_BITSET_H
#define SRSRAN_DYN_BITSET_H #define SRSRAN_DYN_BITSET_H
#include "adt_utils.h" #include "srsran/common/srsran_assert.h"
#include "srsran/srslog/bundled/fmt/format.h" #include "srsran/srslog/bundled/fmt/format.h"
#include <cstdint> #include <cstdint>
#include <inttypes.h> #include <inttypes.h>
@ -43,11 +43,7 @@ public:
void resize(size_t new_size) void resize(size_t new_size)
{ {
if (new_size > max_size()) { srsran_assert(new_size <= max_size(), "ERROR: new size=%zd exceeds bitset capacity=%zd", new_size, max_size());
std::string msg =
"ERROR: new size=" + std::to_string(new_size) + " exceeds bitset capacity=" + std::to_string(max_size());
THROW_BAD_ACCESS(msg.c_str());
}
if (new_size == cur_size) { if (new_size == cur_size) {
return; return;
} }
@ -191,11 +187,10 @@ public:
bounded_bitset<N, reversed>& operator|=(const bounded_bitset<N, reversed>& other) bounded_bitset<N, reversed>& operator|=(const bounded_bitset<N, reversed>& other)
{ {
if (other.size() != size()) { srsran_assert(other.size() == size(),
std::string msg = "operator|= called for bitsets of different sizes (" + std::to_string(size()) + "ERROR: operator|= called for bitsets of different sizes (%zd!=%zd)",
"!=" + std::to_string(other.size()) + ")"; size(),
THROW_BAD_ACCESS(msg.c_str()); other.size());
}
for (size_t i = 0; i < nof_words_(); ++i) { for (size_t i = 0; i < nof_words_(); ++i) {
buffer[i] |= other.buffer[i]; buffer[i] |= other.buffer[i];
} }
@ -204,11 +199,10 @@ public:
bounded_bitset<N, reversed>& operator&=(const bounded_bitset<N, reversed>& other) bounded_bitset<N, reversed>& operator&=(const bounded_bitset<N, reversed>& other)
{ {
if (other.size() != size()) { srsran_assert(other.size() == size(),
std::string msg = "operator&= called for bitsets of different sizes (" + std::to_string(size()) + "ERROR: operator&= called for bitsets of different sizes (%zd!=%zd)",
"!=" + std::to_string(other.size()) + ")"; size(),
THROW_BAD_ACCESS(msg.c_str()); other.size());
}
for (size_t i = 0; i < nof_words_(); ++i) { for (size_t i = 0; i < nof_words_(); ++i) {
buffer[i] &= other.buffer[i]; buffer[i] &= other.buffer[i];
} }
@ -245,10 +239,7 @@ public:
uint64_t to_uint64() const uint64_t to_uint64() const
{ {
if (nof_words_() > 1) { srsran_assert(nof_words_() == 1, "ERROR: cannot convert bitset of size=%zd to uint64_t", size());
std::string msg = "ERROR: cannot convert bitset of size=" + std::to_string(size()) + " to uint64_t";
THROW_BAD_ACCESS(msg.c_str());
}
return get_word_(0); return get_word_(0);
} }
@ -310,11 +301,10 @@ private:
void assert_within_bounds_(size_t pos, bool strict) const void assert_within_bounds_(size_t pos, bool strict) const
{ {
if (pos > size() or (strict and pos == size())) { srsran_assert(pos < size() or (not strict and pos == size()),
std::string msg = "ERROR: index=%zd is out-of-bounds for bitset of size=%zd",
"ERROR: index=" + std::to_string(pos) + "is out of bounds for bitset of size=" + std::to_string(size()); pos,
THROW_BAD_ACCESS(msg.c_str()); size());
}
} }
static word_t maskbit(size_t pos) { return (static_cast<word_t>(1)) << (pos % bits_per_word); } static word_t maskbit(size_t pos) { return (static_cast<word_t>(1)) << (pos % bits_per_word); }

@ -13,6 +13,7 @@
#ifndef SRSRAN_BOUNDED_VECTOR_H #ifndef SRSRAN_BOUNDED_VECTOR_H
#define SRSRAN_BOUNDED_VECTOR_H #define SRSRAN_BOUNDED_VECTOR_H
#include "srsran/adt/detail/type_storage.h"
#include "srsran/common/srsran_assert.h" #include "srsran/common/srsran_assert.h"
#include <iterator> #include <iterator>
#include <memory> #include <memory>
@ -88,12 +89,12 @@ public:
T& operator[](std::size_t i) T& operator[](std::size_t i)
{ {
srsran_assert(i < size_, "Array index is out of bounds."); srsran_assert(i < size_, "Array index is out of bounds.");
return reinterpret_cast<T&>(buffer[i]); return buffer[i].get();
} }
const T& operator[](std::size_t i) const const T& operator[](std::size_t i) const
{ {
srsran_assert(i < size_, "Array index is out of bounds."); srsran_assert(i < size_, "Array index is out of bounds.");
return reinterpret_cast<const T&>(buffer[i]); return buffer[i].get();
} }
T& back() T& back()
{ {
@ -107,8 +108,8 @@ public:
} }
T& front() { return (*this)[0]; } T& front() { return (*this)[0]; }
const T& front() const { return (*this)[0]; } const T& front() const { return (*this)[0]; }
T* data() { return reinterpret_cast<T*>(buffer); } T* data() { return &buffer[0].get(); }
const T* data() const { return reinterpret_cast<const T*>(buffer); } const T* data() const { return &buffer[0].get(); }
// Iterators // Iterators
iterator begin() { return data(); } iterator begin() { return data(); }
@ -226,13 +227,13 @@ private:
static_assert(std::is_default_constructible<T>::value, "T must be default-constructible"); static_assert(std::is_default_constructible<T>::value, "T must be default-constructible");
srsran_assert(N + size_ <= MAX_N, "bounded vector maximum size=%zd was exceeded", MAX_N); srsran_assert(N + size_ <= MAX_N, "bounded vector maximum size=%zd was exceeded", MAX_N);
for (size_type i = size_; i < size_ + N; ++i) { for (size_type i = size_; i < size_ + N; ++i) {
new (&buffer[i]) T(); buffer[i].emplace();
} }
size_ += N; size_ += N;
} }
std::size_t size_ = 0; std::size_t size_ = 0;
typename std::aligned_storage<sizeof(T), alignof(T)>::type buffer[MAX_N]; std::array<detail::type_storage<T>, MAX_N> buffer;
}; };
} // namespace srsran } // namespace srsran

@ -13,6 +13,8 @@
#ifndef CPP_TESTS_INDEX_SEQUENCE_H #ifndef CPP_TESTS_INDEX_SEQUENCE_H
#define CPP_TESTS_INDEX_SEQUENCE_H #define CPP_TESTS_INDEX_SEQUENCE_H
#include <cstddef>
namespace srsran { namespace srsran {
template <std::size_t...> template <std::size_t...>

@ -271,19 +271,15 @@ const T* get_if(const TypeContainer& c)
template <typename T, typename TypeContainer> template <typename T, typename TypeContainer>
T& get(TypeContainer& c) T& get(TypeContainer& c)
{ {
if (c.template is<T>()) { srsran_assert(c.template is<T>(), "Bad access via get<T>");
return c.template get_unchecked<T>(); return c.template get_unchecked<T>();
}
THROW_BAD_ACCESS("in get<T>");
} }
template <typename T, typename TypeContainer> template <typename T, typename TypeContainer>
const T& get(const TypeContainer& c) const T& get(const TypeContainer& c)
{ {
if (c.template is<T>()) { srsran_assert(c.template is<T>(), "Bad access via get<T>");
return c.template get_unchecked<T>(); return c.template get_unchecked<T>();
}
THROW_BAD_ACCESS("in get<T>");
} }
template <size_t I, template <size_t I,

@ -13,7 +13,7 @@
#ifndef SRSRAN_EXPECTED_H #ifndef SRSRAN_EXPECTED_H
#define SRSRAN_EXPECTED_H #define SRSRAN_EXPECTED_H
#include "adt_utils.h" #include "srsran/common/srsran_assert.h"
#include <memory> #include <memory>
#include <system_error> #include <system_error>
@ -21,6 +21,14 @@ namespace srsran {
struct default_error_t {}; struct default_error_t {};
template <typename T, typename E>
class expected;
template <typename T>
struct is_expected : std::false_type {};
template <typename V, typename E>
struct is_expected<expected<V, E> > : std::true_type {};
template <typename T, typename E = default_error_t> template <typename T, typename E = default_error_t>
class expected class expected
{ {
@ -32,6 +40,12 @@ public:
expected(const T& t) : has_val(true), val(t) {} expected(const T& t) : has_val(true), val(t) {}
expected(E&& e) : has_val(false), unexpected(std::forward<E>(e)) {} expected(E&& e) : has_val(false), unexpected(std::forward<E>(e)) {}
expected(const E& e) : has_val(false), unexpected(e) {} expected(const E& e) : has_val(false), unexpected(e) {}
template <
typename U,
typename std::enable_if<std::is_convertible<U, T>::value and not is_expected<typename std::decay<U>::type>::value,
int>::type = 0>
explicit expected(U&& u) : has_val(true), val(std::forward<U>(u))
{}
expected(const expected& other) expected(const expected& other)
{ {
if (other.has_val) { if (other.has_val) {
@ -105,30 +119,22 @@ public:
bool is_error() const { return not has_value(); } bool is_error() const { return not has_value(); }
const T& value() const const T& value() const
{ {
if (not has_val) { srsran_assert(has_value(), "Bad expected<T> value access");
THROW_BAD_ACCESS("Bad expected value access");
}
return val; return val;
} }
T& value() T& value()
{ {
if (not has_val) { srsran_assert(has_value(), "Bad expected<T> value access");
THROW_BAD_ACCESS("Bad expected value access");
}
return val; return val;
} }
const E& error() const const E& error() const
{ {
if (has_val) { srsran_assert(not has_value(), "Bad expected<T> error access");
THROW_BAD_ACCESS("Bad expected error access");
}
return unexpected; return unexpected;
} }
E& error() E& error()
{ {
if (has_val) { srsran_assert(not has_value(), "Bad expected<T> error access");
THROW_BAD_ACCESS("Bad expected error access");
}
return unexpected; return unexpected;
} }

@ -18,8 +18,6 @@
#include "srsran/srslog/srslog.h" #include "srsran/srslog/srslog.h"
#include <cstdio> #include <cstdio>
#include <deque> #include <deque>
#include <limits>
#include <list>
#include <memory> #include <memory>
#include <tuple> #include <tuple>
@ -36,17 +34,17 @@
namespace srsran { namespace srsran {
//! Forward declarations /// Forward declarations
template <typename Derived> template <typename Derived>
class base_fsm_t; class base_fsm_t;
template <typename Derived, typename ParentFSM> template <typename Derived, typename ParentFSM>
class composite_fsm_t; class composite_fsm_t;
//! Check if type T is an FSM /// Check if type T is an FSM
template <typename T> template <typename T>
using is_fsm = std::is_base_of<base_fsm_t<T>, T>; using is_fsm = std::is_base_of<base_fsm_t<T>, T>;
//! Check if type T is a composite FSM /// Check if type T is a composite FSM
template <typename T, typename TCheck = void> template <typename T, typename TCheck = void>
struct is_composite_fsm : public std::false_type {}; struct is_composite_fsm : public std::false_type {};
template <typename T> template <typename T>
@ -259,7 +257,7 @@ struct apply_first_guard_pass<FSM, type_list<> > {
} }
}; };
//! Trigger Event, that will result in a state transition /// Trigger Event that may result in a state transition
template <typename FSM, typename Event> template <typename FSM, typename Event>
struct trigger_visitor { struct trigger_visitor {
using event_t = typename std::decay<Event>::type; using event_t = typename std::decay<Event>::type;
@ -679,10 +677,8 @@ public:
const Result& get_result() const const Result& get_result() const
{ {
if (launch_counter > 0 and base_t::template is_in_state<idle_st>()) { srsran_assert(launch_counter > 0 and base_t::template is_in_state<idle_st>(), "in proc_fsm_t::get_result");
return last_result; return last_result;
}
THROW_BAD_ACCESS("in proc_fsm_t::get_result");
} }
template <typename OtherFSM> template <typename OtherFSM>

@ -13,7 +13,7 @@
#ifndef SRSRAN_INTERVAL_H #ifndef SRSRAN_INTERVAL_H
#define SRSRAN_INTERVAL_H #define SRSRAN_INTERVAL_H
#include "adt_utils.h" #include "srsran/common/srsran_assert.h"
#include "srsran/srslog/bundled/fmt/format.h" #include "srsran/srslog/bundled/fmt/format.h"
#include <cassert> #include <cassert>
#include <string> #include <string>
@ -43,7 +43,7 @@ public:
void set(T start_point, T stop_point) void set(T start_point, T stop_point)
{ {
assert(stop_point >= start_point); srsran_assert(stop_point >= start_point, "interval::set called for invalid range points");
start_ = start_point; start_ = start_point;
stop_ = stop_point; stop_ = stop_point;
} }
@ -51,13 +51,13 @@ public:
void resize_by(T len) void resize_by(T len)
{ {
// Detect length overflows // Detect length overflows
assert(std::is_unsigned<T>::value or (len >= 0 or length() >= -len)); srsran_assert(std::is_unsigned<T>::value or (len >= 0 or length() >= -len), "Resulting interval would be invalid");
stop_ += len; stop_ += len;
} }
void resize_to(T len) void resize_to(T len)
{ {
assert(std::is_unsigned<T>::value or len >= 0); srsran_assert(std::is_unsigned<T>::value or len >= 0, "Interval width must be positive");
stop_ = start_ + len; stop_ = start_ + len;
} }

@ -13,6 +13,8 @@
#ifndef SRSRAN_MOVE_CALLBACK_H #ifndef SRSRAN_MOVE_CALLBACK_H
#define SRSRAN_MOVE_CALLBACK_H #define SRSRAN_MOVE_CALLBACK_H
#include "detail/type_storage.h"
#include "srsran/common/srsran_assert.h"
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
#include <cstdio> #include <cstdio>
@ -25,23 +27,11 @@
#define THROW_BAD_FUNCTION_CALL(const char* cause) throw std::bad_function_call{}; #define THROW_BAD_FUNCTION_CALL(const char* cause) throw std::bad_function_call{};
#else #else
#define THROW_BAD_FUNCTION_CALL(cause) \ #define THROW_BAD_FUNCTION_CALL(cause) \
fprintf(stderr, "ERROR: exception thrown due to bad function call (cause: %s)\n", cause); \ srsran_assert(false, "ERROR: exception thrown due to bad function call (cause: %s)\n", cause);
std::abort()
#endif #endif
namespace srsran { namespace srsran {
// NOTE: gcc 4.8.5 is missing std::max_align_t. Need to create a struct
union max_alignment_t {
char c;
float f;
uint32_t i;
uint64_t i2;
double d;
long double d2;
uint32_t* ptr;
};
//! Size of the buffer used by "move_callback<R(Args...)>" to store functors without calling "new" //! Size of the buffer used by "move_callback<R(Args...)>" to store functors without calling "new"
constexpr size_t default_buffer_size = 32; constexpr size_t default_buffer_size = 32;
@ -68,10 +58,13 @@ class empty_table_t : public oper_table_t<R, Args...>
{ {
public: public:
constexpr empty_table_t() = default; constexpr empty_table_t() = default;
R call(void* src, Args&&... args) const final { THROW_BAD_FUNCTION_CALL("function ptr is empty"); } R call(void* src, Args&&... args) const final
void move(void* src, void* dest) const final {} {
void dtor(void* src) const final {} srsran_terminate("ERROR: bad function call (cause: function ptr is empty)");
bool is_in_small_buffer() const final { return true; } }
void move(void* src, void* dest) const final {}
void dtor(void* src) const final {}
bool is_in_small_buffer() const final { return true; }
}; };
//! specialization of move/call/destroy operations for when the functor is stored in "move_callback<R(Args...)>" buffer //! specialization of move/call/destroy operations for when the functor is stored in "move_callback<R(Args...)>" buffer
@ -126,7 +119,7 @@ template <class R, class... Args, size_t Capacity>
class move_callback<R(Args...), Capacity> class move_callback<R(Args...), Capacity>
{ {
static constexpr size_t capacity = Capacity >= sizeof(void*) ? Capacity : sizeof(void*); ///< size of buffer static constexpr size_t capacity = Capacity >= sizeof(void*) ? Capacity : sizeof(void*); ///< size of buffer
using storage_t = typename std::aligned_storage<capacity, alignof(max_alignment_t)>::type; using storage_t = typename std::aligned_storage<capacity, alignof(detail::max_alignment_t)>::type;
using oper_table_t = task_details::oper_table_t<R, Args...>; using oper_table_t = task_details::oper_table_t<R, Args...>;
static constexpr task_details::empty_table_t<R, Args...> empty_table{}; static constexpr task_details::empty_table_t<R, Args...> empty_table{};

@ -16,10 +16,14 @@
#include "srsran/srslog/srslog.h" #include "srsran/srslog/srslog.h"
#include <cstdio> #include <cstdio>
#ifdef ASSERTS_ENABLED
#define srsran_unlikely(expr) __builtin_expect(!!(expr), 0) #define srsran_unlikely(expr) __builtin_expect(!!(expr), 0)
#define srsran_terminate(fmt, ...) \
std::fprintf(stderr, "%s:%d: " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__); \
std::abort()
#ifdef ASSERTS_ENABLED
/** /**
* Macro that asserts condition is true. If false, it logs the remaining parameters, prints the backtrace and closes * Macro that asserts condition is true. If false, it logs the remaining parameters, prints the backtrace and closes
* the application * the application
@ -27,8 +31,7 @@
#define srsran_assert(condition, fmt, ...) \ #define srsran_assert(condition, fmt, ...) \
do { \ do { \
if (srsran_unlikely(not(condition))) { \ if (srsran_unlikely(not(condition))) { \
std::fprintf(stderr, "%s:%d: " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__); \ srsran_terminate(fmt, ##__VA_ARGS__); \
std::abort(); \
} \ } \
} while (0) } while (0)

@ -49,3 +49,7 @@ add_test(circular_buffer_test circular_buffer_test)
add_executable(circular_map_test circular_map_test.cc) add_executable(circular_map_test circular_map_test.cc)
target_link_libraries(circular_map_test srsran_common) target_link_libraries(circular_map_test srsran_common)
add_test(circular_map_test circular_map_test) add_test(circular_map_test circular_map_test)
add_executable(fsm_test fsm_test.cc)
target_link_libraries(fsm_test srsran_common)
add_test(fsm_test fsm_test)

@ -10,7 +10,7 @@
* *
*/ */
#include "srsran/common/fsm.h" #include "srsran/adt/fsm.h"
#include "srsran/common/test_common.h" #include "srsran/common/test_common.h"
///////////////////////////// /////////////////////////////

@ -64,10 +64,6 @@ add_executable(tti_point_test tti_point_test.cc)
target_link_libraries(tti_point_test srsran_common) target_link_libraries(tti_point_test srsran_common)
add_test(tti_point_test tti_point_test) add_test(tti_point_test tti_point_test)
add_executable(fsm_test fsm_test.cc)
target_link_libraries(fsm_test srsran_common)
add_test(fsm_test fsm_test)
add_executable(choice_type_test choice_type_test.cc) add_executable(choice_type_test choice_type_test.cc)
target_link_libraries(choice_type_test srsran_common) target_link_libraries(choice_type_test srsran_common)
add_test(choice_type_test choice_type_test) add_test(choice_type_test choice_type_test)

@ -15,7 +15,7 @@
#include "rrc.h" #include "rrc.h"
#include "rrc_ue.h" #include "rrc_ue.h"
#include "srsran/common/fsm.h" #include "srsran/adt/fsm.h"
#include <map> #include <map>
namespace srsenb { namespace srsenb {

@ -13,8 +13,8 @@
#ifndef SRSRAN_PHY_CONTROLLER_H #ifndef SRSRAN_PHY_CONTROLLER_H
#define SRSRAN_PHY_CONTROLLER_H #define SRSRAN_PHY_CONTROLLER_H
#include "srsran/adt/fsm.h"
#include "srsran/adt/observer.h" #include "srsran/adt/observer.h"
#include "srsran/common/fsm.h"
#include "srsran/common/task_scheduler.h" #include "srsran/common/task_scheduler.h"
#include "srsran/interfaces/ue_phy_interfaces.h" #include "srsran/interfaces/ue_phy_interfaces.h"
#include "srsran/interfaces/ue_rrc_interfaces.h" #include "srsran/interfaces/ue_rrc_interfaces.h"

Loading…
Cancel
Save