diff --git a/lib/include/srslte/adt/adt_utils.h b/lib/include/srslte/adt/adt_utils.h new file mode 100644 index 000000000..aefd52f90 --- /dev/null +++ b/lib/include/srslte/adt/adt_utils.h @@ -0,0 +1,44 @@ +/* + * Copyright 2013-2020 Software Radio Systems Limited + * + * This file is part of srsLTE. + * + * srsLTE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsLTE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ + +#ifndef SRSLTE_ADT_UTILS_H +#define SRSLTE_ADT_UTILS_H + +namespace srslte { + +#if defined(__cpp_exceptions) && (1 == __cpp_exceptions) +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}; +#else +#define THROW_BAD_ACCESS(msg) \ + fprintf(stderr, "ERROR: exception thrown with %s", msg); \ + std::abort() +#endif + +} // namespace srslte + +#endif // SRSLTE_ADT_UTILS_H diff --git a/lib/include/srslte/common/bounded_bitset.h b/lib/include/srslte/adt/bounded_bitset.h similarity index 82% rename from lib/include/srslte/common/bounded_bitset.h rename to lib/include/srslte/adt/bounded_bitset.h index e08eee280..9a88acb06 100644 --- a/lib/include/srslte/common/bounded_bitset.h +++ b/lib/include/srslte/adt/bounded_bitset.h @@ -22,7 +22,7 @@ #ifndef SRSLTE_DYN_BITSET_H #define SRSLTE_DYN_BITSET_H -#include "srslte/common/logmap.h" +#include "adt_utils.h" #include #include #include @@ -52,8 +52,9 @@ public: void resize(size_t new_size) noexcept { if (new_size > max_size()) { - srslte::logmap::get("COMM")->error("ERROR: bitset resize out of bounds: %zd>=%zd\n", max_size(), new_size); - return; + 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()); } else if (new_size == cur_size) { return; } @@ -66,10 +67,7 @@ public: void set(size_t pos, bool val) noexcept { - if (pos >= size()) { - srslte::logmap::get("COMM")->error("ERROR: bitset out of bounds: %zd>=%zd\n", pos, size()); - return; - } + assert_within_bounds_(pos, true); if (val) { set_(pos); } else { @@ -79,19 +77,13 @@ public: void set(size_t pos) noexcept { - if (pos >= size()) { - srslte::logmap::get("COMM")->error("ERROR: bitset out of bounds: %zd>=%zd\n", pos, size()); - return; - } + assert_within_bounds_(pos, true); set_(pos); } void reset(size_t pos) noexcept { - if (pos >= size()) { - srslte::logmap::get("COMM")->error("ERROR: bitset out of bounds: %zd>=%zd\n", pos, size()); - return; - } + assert_within_bounds_(pos, true); reset_(pos); } @@ -104,10 +96,7 @@ public: bool test(size_t pos) const noexcept { - if (pos >= size()) { - srslte::logmap::get("COMM")->error("ERROR: bitset out of bounds: %zd>=%zd\n", pos, size()); - return false; - } + assert_within_bounds_(pos, true); return test_(pos); } @@ -122,11 +111,8 @@ public: bounded_bitset& fill(size_t startpos, size_t endpos, bool value = true) noexcept { - if (endpos > size() or startpos > endpos) { - srslte::logmap::get("COMM")->error( - "ERROR: bounds (%zd, %zd) are not valid for bitset of size: %zd\n", startpos, endpos, size()); - return *this; - } + assert_within_bounds_(startpos, false); + assert_within_bounds_(endpos, false); // NOTE: can be optimized if (value) { for (size_t i = startpos; i < endpos; ++i) { @@ -167,11 +153,8 @@ public: bool any(size_t start, size_t stop) const noexcept { - if (start > stop or stop > size()) { - srslte::logmap::get("COMM")->error( - "ERROR: bounds (%zd, %zd) are not valid for bitset of size: %zd\n", start, stop, size()); - return false; - } + assert_within_bounds_(start, false); + assert_within_bounds_(stop, false); // NOTE: can be optimized for (size_t i = start; i < stop; ++i) { if (test_(i)) { @@ -214,9 +197,9 @@ public: bounded_bitset& operator|=(const bounded_bitset& other) noexcept { if (other.size() != size()) { - srslte::logmap::get("COMM")->error( - "ERROR: operator|= called for bitsets of different sizes (%zd!=%zd)\n", size(), other.size()); - return *this; + std::string msg = "operator|= called for bitsets of different sizes (" + std::to_string(size()) + + "!=" + std::to_string(other.size()) + ")"; + THROW_BAD_ACCESS(msg.c_str()); } for (size_t i = 0; i < nof_words_(); ++i) { buffer[i] |= other.buffer[i]; @@ -227,9 +210,9 @@ public: bounded_bitset& operator&=(const bounded_bitset& other) noexcept { if (other.size() != size()) { - srslte::logmap::get("COMM")->error( - "ERROR: operator&= called for bitsets of different sizes (%zd!=%zd)\n", size(), other.size()); - return *this; + std::string msg = "operator&= called for bitsets of different sizes (" + std::to_string(size()) + + "!=" + std::to_string(other.size()) + ")"; + THROW_BAD_ACCESS(msg.c_str()); } for (size_t i = 0; i < nof_words_(); ++i) { buffer[i] &= other.buffer[i]; @@ -267,8 +250,8 @@ public: uint64_t to_uint64() const noexcept { if (nof_words_() > 1) { - srslte::logmap::get("COMM")->error("ERROR: cannot convert bitset of size %zd bits to uint64_t\n", size()); - return 0; + 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); } @@ -327,6 +310,15 @@ private: size_t word_idx_(size_t pos) const { return pos / bits_per_word; } + void assert_within_bounds_(size_t pos, bool strict) const + { + if (pos > size() or (strict and pos == size())) { + std::string msg = + "ERROR: index=" + std::to_string(pos) + "is out of bounds for bitset of size=" + std::to_string(size()); + THROW_BAD_ACCESS(msg.c_str()); + } + } + static word_t maskbit(size_t pos) { return (static_cast(1)) << (pos % bits_per_word); } static size_t max_nof_words_() { return (N - 1) / bits_per_word + 1; } diff --git a/lib/include/srslte/common/expected.h b/lib/include/srslte/adt/expected.h similarity index 87% rename from lib/include/srslte/common/expected.h rename to lib/include/srslte/adt/expected.h index ac1ce603a..75f711d9e 100644 --- a/lib/include/srslte/common/expected.h +++ b/lib/include/srslte/adt/expected.h @@ -22,31 +22,19 @@ #ifndef SRSLTE_EXPECTED_H #define SRSLTE_EXPECTED_H +#include "adt_utils.h" #include #include namespace srslte { -#if defined(__cpp_exceptions) && (1 == __cpp_exceptions) -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}; -#else -#define THROW_BAD_ACCESS(msg) \ - fprintf(stderr, "ERROR: exception thrown with %s", msg); \ - std::abort() -#endif - struct default_error_t {}; template class expected { + static_assert(not std::is_same::value, "Expected and unexpected types cannot be of the same type"); + public: expected() : has_val(true), val(T{}) {} expected(T&& t) : has_val(true), val(std::forward(t)) {} diff --git a/lib/include/srslte/common/move_callback.h b/lib/include/srslte/adt/move_callback.h similarity index 99% rename from lib/include/srslte/common/move_callback.h rename to lib/include/srslte/adt/move_callback.h index 5f1a29569..dfdbdccd0 100644 --- a/lib/include/srslte/common/move_callback.h +++ b/lib/include/srslte/adt/move_callback.h @@ -23,10 +23,10 @@ #define SRSLTE_MOVE_CALLBACK_H #include +#include #include #include #include -#include #include #if defined(__cpp_exceptions) && (1 == __cpp_exceptions) diff --git a/lib/include/srslte/common/block_queue.h b/lib/include/srslte/common/block_queue.h index 626dfee8c..12804aa83 100644 --- a/lib/include/srslte/common/block_queue.h +++ b/lib/include/srslte/common/block_queue.h @@ -29,7 +29,7 @@ #ifndef SRSLTE_BLOCK_QUEUE_H #define SRSLTE_BLOCK_QUEUE_H -#include "srslte/common/expected.h" +#include "srslte/adt/expected.h" #include #include #include diff --git a/lib/include/srslte/common/fsm.h b/lib/include/srslte/common/fsm.h index 4664e2893..6e79d82ae 100644 --- a/lib/include/srslte/common/fsm.h +++ b/lib/include/srslte/common/fsm.h @@ -22,8 +22,8 @@ #ifndef SRSLTE_FSM_H #define SRSLTE_FSM_H +#include "srslte/adt/move_callback.h" #include "srslte/common/logmap.h" -#include "srslte/common/move_callback.h" #include "type_utils.h" #include #include diff --git a/lib/include/srslte/common/multiqueue.h b/lib/include/srslte/common/multiqueue.h index 64d0b534e..f9c851a36 100644 --- a/lib/include/srslte/common/multiqueue.h +++ b/lib/include/srslte/common/multiqueue.h @@ -28,7 +28,7 @@ #ifndef SRSLTE_MULTIQUEUE_H #define SRSLTE_MULTIQUEUE_H -#include "move_callback.h" +#include "srslte/adt/move_callback.h" #include #include #include diff --git a/lib/include/srslte/common/stack_procedure.h b/lib/include/srslte/common/stack_procedure.h index cdd9a7469..9a1da017a 100644 --- a/lib/include/srslte/common/stack_procedure.h +++ b/lib/include/srslte/common/stack_procedure.h @@ -19,7 +19,7 @@ * */ -#include "srslte/common/move_callback.h" +#include "srslte/adt/move_callback.h" #include #include #include diff --git a/lib/include/srslte/common/type_utils.h b/lib/include/srslte/common/type_utils.h index 707a49ca0..c665dec31 100644 --- a/lib/include/srslte/common/type_utils.h +++ b/lib/include/srslte/common/type_utils.h @@ -22,7 +22,7 @@ #ifndef SRSLTE_TYPE_UTILS_H #define SRSLTE_TYPE_UTILS_H -#include "expected.h" +#include "srslte/adt/expected.h" #include #include #include diff --git a/lib/test/adt/CMakeLists.txt b/lib/test/adt/CMakeLists.txt index b5abc6263..eed219eaa 100644 --- a/lib/test/adt/CMakeLists.txt +++ b/lib/test/adt/CMakeLists.txt @@ -26,7 +26,14 @@ add_executable(scope_exit_test scope_exit_test.cc) target_link_libraries(scope_exit_test srslte_common) add_test(scope_exit_test scope_exit_test) +add_executable(expected_test expected_test.cc) +target_link_libraries(expected_test srslte_common) +add_test(expected_test expected_test) + +add_executable(bounded_bitset_test bounded_bitset_test.cc) +target_link_libraries(bounded_bitset_test srslte_common) +add_test(bounded_bitset_test bounded_bitset_test) + add_executable(span_test span_test.cc) target_link_libraries(span_test srslte_common) add_test(span_test span_test) - diff --git a/lib/test/common/expected_test.cc b/lib/test/adt/expected_test.cc similarity index 98% rename from lib/test/common/expected_test.cc rename to lib/test/adt/expected_test.cc index 90c7ada8f..30098ea10 100644 --- a/lib/test/common/expected_test.cc +++ b/lib/test/adt/expected_test.cc @@ -19,7 +19,7 @@ * */ -#include "srslte/common/expected.h" +#include "srslte/adt/expected.h" #include "srslte/common/test_common.h" int test_expected_trivial() diff --git a/lib/test/common/CMakeLists.txt b/lib/test/common/CMakeLists.txt index 688b32feb..801baa557 100644 --- a/lib/test/common/CMakeLists.txt +++ b/lib/test/common/CMakeLists.txt @@ -90,10 +90,6 @@ add_executable(choice_type_test choice_type_test.cc) target_link_libraries(choice_type_test srslte_common) add_test(choice_type_test choice_type_test) -add_executable(expected_test expected_test.cc) -target_link_libraries(expected_test srslte_common) -add_test(expected_test expected_test) - add_executable(task_scheduler_test task_scheduler_test.cc) target_link_libraries(task_scheduler_test srslte_common) add_test(task_scheduler_test task_scheduler_test) diff --git a/lib/test/common/queue_test.cc b/lib/test/common/queue_test.cc index dc1b50a32..148526659 100644 --- a/lib/test/common/queue_test.cc +++ b/lib/test/common/queue_test.cc @@ -19,7 +19,7 @@ * */ -#include "srslte/common/move_callback.h" +#include "srslte/adt/move_callback.h" #include "srslte/common/multiqueue.h" #include "srslte/common/thread_pool.h" #include diff --git a/srsenb/hdr/stack/mac/scheduler_common.h b/srsenb/hdr/stack/mac/scheduler_common.h index 77f91159b..70ff35503 100644 --- a/srsenb/hdr/stack/mac/scheduler_common.h +++ b/srsenb/hdr/stack/mac/scheduler_common.h @@ -22,7 +22,7 @@ #ifndef SRSLTE_SCHEDULER_COMMON_H #define SRSLTE_SCHEDULER_COMMON_H -#include "srslte/common/bounded_bitset.h" +#include "srslte/adt/bounded_bitset.h" #include "srslte/interfaces/sched_interface.h" namespace srsenb { diff --git a/srsenb/hdr/stack/mac/scheduler_grid.h b/srsenb/hdr/stack/mac/scheduler_grid.h index bd4c63351..804fa8522 100644 --- a/srsenb/hdr/stack/mac/scheduler_grid.h +++ b/srsenb/hdr/stack/mac/scheduler_grid.h @@ -24,7 +24,7 @@ #include "lib/include/srslte/interfaces/sched_interface.h" #include "scheduler_ue.h" -#include "srslte/common/bounded_bitset.h" +#include "srslte/adt/bounded_bitset.h" #include "srslte/common/log.h" #include #include diff --git a/srsenb/hdr/stack/mac/scheduler_harq.h b/srsenb/hdr/stack/mac/scheduler_harq.h index 21d1607af..a8fde7a45 100644 --- a/srsenb/hdr/stack/mac/scheduler_harq.h +++ b/srsenb/hdr/stack/mac/scheduler_harq.h @@ -22,7 +22,7 @@ #ifndef SRSENB_SCHEDULER_HARQ_H #define SRSENB_SCHEDULER_HARQ_H -#include "srslte/common/bounded_bitset.h" +#include "srslte/adt/bounded_bitset.h" #include "srslte/common/log.h" #include "srslte/common/tti_point.h" #include "srslte/interfaces/sched_interface.h"