mirror of https://github.com/PentHertz/srsLTE.git
- Simplified the usage of span now with implicit constructors as it should be.
- Added overload for generic containers that have size and data members like vector. - Removed unnecessary uses of make_span.
This commit is contained in:
parent
158edd4fe7
commit
072e84cec8
|
@ -33,12 +33,53 @@ namespace srslte {
|
|||
|
||||
/// The class template span describes an object that can refer to a contiguous sequence of objects with the first
|
||||
/// element of the sequence at position zero.
|
||||
/// It is encouraged to use the make_span() helper functions for creating new spans instead of using the constructors
|
||||
/// directly. This way is more explicit in code and makes the developer think first to make sure the lifetime of the
|
||||
/// sequence outlasts the new created span.
|
||||
template <typename T>
|
||||
class span
|
||||
{
|
||||
/// Helper traits used by SFINAE expressions in constructors.
|
||||
|
||||
template <typename... Ts>
|
||||
struct make_void {
|
||||
typedef void type;
|
||||
};
|
||||
template <typename... Ts>
|
||||
using void_t = typename make_void<Ts...>::type;
|
||||
|
||||
template <typename U>
|
||||
struct is_span : std::false_type {};
|
||||
template <typename U>
|
||||
struct is_span<span<U> > : std::true_type {};
|
||||
|
||||
template <typename U>
|
||||
struct is_std_array : std::false_type {};
|
||||
template <typename U, std::size_t N>
|
||||
struct is_std_array<std::array<U, N> > : std::true_type {};
|
||||
|
||||
template <typename U>
|
||||
using remove_cvref_t = typename std::remove_cv<typename std::remove_reference<U>::type>::type;
|
||||
|
||||
template <class Container, class U, class = void>
|
||||
struct is_container_compatible : public std::false_type {};
|
||||
template <class Container, class U>
|
||||
struct is_container_compatible<
|
||||
Container,
|
||||
U,
|
||||
void_t<
|
||||
// Check if the container type has data and size members.
|
||||
decltype(std::declval<Container>().data()),
|
||||
decltype(std::declval<Container>().size()),
|
||||
// Container should not be a span.
|
||||
typename std::enable_if<!is_span<remove_cvref_t<Container> >::value, int>::type,
|
||||
// Container should not be a std::array.
|
||||
typename std::enable_if<!is_std_array<remove_cvref_t<Container> >::value, int>::type,
|
||||
// Container should not be an array.
|
||||
typename std::enable_if<!std::is_array<remove_cvref_t<Container> >::value, int>::type,
|
||||
// Check type compatibility between the contained type and the span type.
|
||||
typename std::enable_if<
|
||||
std::is_convertible<typename std::remove_pointer<decltype(std::declval<Container>().data())>::type (*)[],
|
||||
U (*)[]>::value,
|
||||
int>::type> > : public std::true_type {};
|
||||
|
||||
public:
|
||||
/// Member types.
|
||||
using element_type = T;
|
||||
|
@ -56,10 +97,10 @@ public:
|
|||
constexpr span() noexcept = default;
|
||||
|
||||
/// Constructs a span that is a view over the range [ptr, ptr + len).
|
||||
constexpr explicit span(pointer ptr, size_type len) noexcept : ptr(ptr), len(len) {}
|
||||
constexpr span(pointer ptr, size_type len) noexcept : ptr(ptr), len(len) {}
|
||||
|
||||
/// Constructs a span that is a view over the range [first, last).
|
||||
constexpr explicit span(pointer first, pointer last) noexcept : ptr(first), len(last - first) {}
|
||||
constexpr span(pointer first, pointer last) noexcept : ptr(first), len(last - first) {}
|
||||
|
||||
/// Constructs a span that is a view over the array arr.
|
||||
template <std::size_t N>
|
||||
|
@ -80,6 +121,18 @@ public:
|
|||
constexpr span(const std::array<U, N>& arr) noexcept : ptr(arr.data()), len(N)
|
||||
{}
|
||||
|
||||
/// Constructs a span that is a view over the container c.
|
||||
template <typename Container,
|
||||
typename std::enable_if<is_container_compatible<Container, element_type>::value, int>::type = 0>
|
||||
constexpr span(Container& c) noexcept : ptr(c.data()), len(c.size())
|
||||
{}
|
||||
|
||||
/// Constructs a span that is a view over the container c.
|
||||
template <typename Container,
|
||||
typename std::enable_if<is_container_compatible<const Container, element_type>::value, int>::type = 0>
|
||||
constexpr span(const Container& c) noexcept : ptr(c.data()), len(c.size())
|
||||
{}
|
||||
|
||||
template <typename U, typename std::enable_if<std::is_convertible<U (*)[], element_type (*)[]>::value, int>::type = 0>
|
||||
constexpr span(const span<U>& other) noexcept : ptr(other.data()), len(other.size())
|
||||
{}
|
||||
|
@ -156,7 +209,7 @@ public:
|
|||
span<element_type> subspan(size_type offset, size_type count) const
|
||||
{
|
||||
assert(count <= size() - offset && "size out of bounds!");
|
||||
return span{data() + offset, count};
|
||||
return {data() + offset, count};
|
||||
}
|
||||
|
||||
/// Returns true if the input span has the same elements as this.
|
||||
|
@ -179,40 +232,6 @@ inline bool operator!=(span<T> lhs, span<T> rhs)
|
|||
return not lhs.equals(rhs);
|
||||
}
|
||||
|
||||
///
|
||||
/// Helpers to construct span objects from different types of contiguous containers.
|
||||
///
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
inline span<T> make_span(T (&arr)[N])
|
||||
{
|
||||
return span<T>{arr};
|
||||
}
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
inline span<T> make_span(std::array<T, N>& arr)
|
||||
{
|
||||
return span<T>{arr};
|
||||
}
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
inline span<const T> make_span(const std::array<T, N>& arr)
|
||||
{
|
||||
return span<const T>{arr};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline span<T> make_span(std::vector<T>& v)
|
||||
{
|
||||
return span<T>{v.data(), v.size()};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline span<const T> make_span(const std::vector<T>& v)
|
||||
{
|
||||
return span<const T>{v.data(), v.size()};
|
||||
}
|
||||
|
||||
} // namespace srslte
|
||||
|
||||
#endif // SRSLTE_SPAN_H
|
||||
|
|
|
@ -27,7 +27,7 @@ int test_span_access()
|
|||
std::array<int, 7> values{1, 2, 3, 4, 5, 6, 7};
|
||||
|
||||
{
|
||||
auto view = srslte::make_span(values);
|
||||
srslte::span<int> view = values;
|
||||
|
||||
// access operators
|
||||
TESTASSERT(view.size() == 7);
|
||||
|
@ -56,7 +56,7 @@ int test_span_conversion()
|
|||
|
||||
{
|
||||
// TEST: changing individual values
|
||||
auto v = srslte::make_span(values), v2 = srslte::make_span(values2);
|
||||
srslte::span<int> v = values, v2 = values2;
|
||||
TESTASSERT(v == v2);
|
||||
|
||||
v[0] = 3;
|
||||
|
@ -68,7 +68,7 @@ int test_span_conversion()
|
|||
|
||||
{
|
||||
// TEST: const context
|
||||
const auto v = srslte::make_span(values), v2 = srslte::make_span(values2);
|
||||
const srslte::span<int> v = values, v2 = values2;
|
||||
TESTASSERT(v != v2);
|
||||
TESTASSERT(v[0] == 3);
|
||||
TESTASSERT(v2[0] == 2);
|
||||
|
@ -78,8 +78,8 @@ int test_span_conversion()
|
|||
|
||||
{
|
||||
// TEST: raw arrays
|
||||
int carray[] = {2, 3, 4, 5, 6, 7, 8};
|
||||
auto v = srslte::make_span(values), v2 = srslte::make_span(carray);
|
||||
int carray[] = {2, 3, 4, 5, 6, 7, 8};
|
||||
srslte::span<int> v = values, v2 = carray;
|
||||
TESTASSERT(v == v2);
|
||||
TESTASSERT(v2.size() == v.size());
|
||||
}
|
||||
|
|
|
@ -430,7 +430,7 @@ int test_s1ap_mobility(mobility_test_params test_params)
|
|||
0x01, 0x48, 0x04, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0xa0, 0x07, 0xa0,
|
||||
0x10, 0x00, 0x01, 0x00, 0x05, 0x00, 0xa7, 0xd0, 0xc1, 0xf6, 0xaf, 0x3e, 0x12, 0xcc,
|
||||
0x86, 0x0d, 0x30, 0x00, 0x0b, 0x5a, 0x02, 0x17, 0x86, 0x00, 0x05, 0xa0, 0x20};
|
||||
test_helpers::copy_msg_to_buffer(pdu, srslte::make_span(ho_cmd_rrc_container));
|
||||
test_helpers::copy_msg_to_buffer(pdu, ho_cmd_rrc_container);
|
||||
TESTASSERT(s1ap.last_enb_status.rnti != tester.rnti);
|
||||
tester.rrc.ho_preparation_complete(tester.rnti, true, std::move(pdu));
|
||||
TESTASSERT(s1ap.last_enb_status.status_present);
|
||||
|
|
|
@ -228,7 +228,7 @@ int bring_rrc_to_reconf_state(srsenb::rrc& rrc, srslte::timer_handler& timers, u
|
|||
|
||||
// Send RRCConnectionRequest
|
||||
uint8_t rrc_conn_request[] = {0x40, 0x12, 0xf6, 0xfb, 0xe2, 0xc6};
|
||||
copy_msg_to_buffer(pdu, srslte::make_span(rrc_conn_request));
|
||||
copy_msg_to_buffer(pdu, rrc_conn_request);
|
||||
rrc.write_pdu(rnti, 0, std::move(pdu));
|
||||
timers.step_all();
|
||||
rrc.tti_clock();
|
||||
|
@ -237,7 +237,7 @@ int bring_rrc_to_reconf_state(srsenb::rrc& rrc, srslte::timer_handler& timers, u
|
|||
uint8_t rrc_conn_setup_complete[] = {0x20, 0x00, 0x40, 0x2e, 0x90, 0x50, 0x49, 0xe8, 0x06, 0x0e, 0x82, 0xa2,
|
||||
0x17, 0xec, 0x13, 0xe2, 0x0f, 0x00, 0x02, 0x02, 0x5e, 0xdf, 0x7c, 0x58,
|
||||
0x05, 0xc0, 0xc0, 0x00, 0x08, 0x04, 0x03, 0xa0, 0x23, 0x23, 0xc0};
|
||||
copy_msg_to_buffer(pdu, srslte::make_span(rrc_conn_setup_complete));
|
||||
copy_msg_to_buffer(pdu, rrc_conn_setup_complete);
|
||||
rrc.write_pdu(rnti, 1, std::move(pdu));
|
||||
timers.step_all();
|
||||
rrc.tti_clock();
|
||||
|
@ -267,7 +267,7 @@ int bring_rrc_to_reconf_state(srsenb::rrc& rrc, srslte::timer_handler& timers, u
|
|||
|
||||
// Send SecurityModeComplete
|
||||
uint8_t sec_mode_complete[] = {0x28, 0x00};
|
||||
copy_msg_to_buffer(pdu, srslte::make_span(sec_mode_complete));
|
||||
copy_msg_to_buffer(pdu, sec_mode_complete);
|
||||
rrc.write_pdu(rnti, 1, std::move(pdu));
|
||||
timers.step_all();
|
||||
rrc.tti_clock();
|
||||
|
@ -275,14 +275,14 @@ int bring_rrc_to_reconf_state(srsenb::rrc& rrc, srslte::timer_handler& timers, u
|
|||
// send UE cap info
|
||||
uint8_t ue_cap_info[] = {0x38, 0x01, 0x01, 0x0c, 0x98, 0x00, 0x00, 0x18, 0x00, 0x0f,
|
||||
0x30, 0x20, 0x80, 0x00, 0x01, 0x00, 0x0e, 0x01, 0x00, 0x00};
|
||||
copy_msg_to_buffer(pdu, srslte::make_span(ue_cap_info));
|
||||
copy_msg_to_buffer(pdu, ue_cap_info);
|
||||
rrc.write_pdu(rnti, 1, std::move(pdu));
|
||||
timers.step_all();
|
||||
rrc.tti_clock();
|
||||
|
||||
// RRCConnectionReconfiguration was sent. Send RRCConnectionReconfigurationComplete
|
||||
uint8_t rrc_conn_reconf_complete[] = {0x10, 0x00};
|
||||
copy_msg_to_buffer(pdu, srslte::make_span(rrc_conn_reconf_complete));
|
||||
copy_msg_to_buffer(pdu, rrc_conn_reconf_complete);
|
||||
rrc.write_pdu(rnti, 1, std::move(pdu));
|
||||
timers.step_all();
|
||||
rrc.tti_clock();
|
||||
|
|
Loading…
Reference in New Issue