encoding+lp+net: simplify with if constexpr
Change-Id: Ie2b45a502c59e5cb7181628e691f7aaaf7509d84
This commit is contained in:
1 parent
581dd52b0d
commit
21b7f1b379
8 files changed
+147
-254
No files matched your search
@@ -181,73 +181,64 @@ namespace detail {
|
||||
* @brief Create a binary block copying from RandomAccessIterator.
|
||||
*/
|
||||
template<class Iterator>
|
||||
class BinaryBlockFast
|
||||
Block
|
||||
makeBinaryBlockFast(uint32_t type, Iterator first, Iterator last)
|
||||
{
|
||||
public:
|
||||
BOOST_CONCEPT_ASSERT((boost::RandomAccessIterator<Iterator>));
|
||||
|
||||
static Block
|
||||
makeBlock(uint32_t type, Iterator first, Iterator last)
|
||||
{
|
||||
EncodingEstimator estimator;
|
||||
size_t valueLength = last - first;
|
||||
size_t totalLength = valueLength;
|
||||
totalLength += estimator.prependVarNumber(valueLength);
|
||||
totalLength += estimator.prependVarNumber(type);
|
||||
EncodingEstimator estimator;
|
||||
size_t valueLength = last - first;
|
||||
size_t totalLength = valueLength;
|
||||
totalLength += estimator.prependVarNumber(valueLength);
|
||||
totalLength += estimator.prependVarNumber(type);
|
||||
|
||||
EncodingBuffer encoder(totalLength, 0);
|
||||
encoder.prependRange(first, last);
|
||||
encoder.prependVarNumber(valueLength);
|
||||
encoder.prependVarNumber(type);
|
||||
EncodingBuffer encoder(totalLength, 0);
|
||||
encoder.prependRange(first, last);
|
||||
encoder.prependVarNumber(valueLength);
|
||||
encoder.prependVarNumber(type);
|
||||
|
||||
return encoder.block();
|
||||
}
|
||||
};
|
||||
return encoder.block();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create a binary block copying from generic InputIterator.
|
||||
*/
|
||||
template<class Iterator>
|
||||
class BinaryBlockSlow
|
||||
Block
|
||||
makeBinaryBlockSlow(uint32_t type, Iterator first, Iterator last)
|
||||
{
|
||||
public:
|
||||
BOOST_CONCEPT_ASSERT((boost::InputIterator<Iterator>));
|
||||
|
||||
static Block
|
||||
makeBlock(uint32_t type, Iterator first, Iterator last)
|
||||
{
|
||||
// reserve 4 bytes in front (common for 1(type)-3(length) encoding
|
||||
// Actual size will be adjusted as necessary by the encoder
|
||||
EncodingBuffer encoder(4, 4);
|
||||
size_t valueLength = encoder.appendRange(first, last);
|
||||
encoder.prependVarNumber(valueLength);
|
||||
encoder.prependVarNumber(type);
|
||||
// Reserve 4 bytes in front, common for 1(type)-3(length) encoding.
|
||||
// Actual size will be adjusted as necessary by the encoder.
|
||||
EncodingBuffer encoder(4, 4);
|
||||
size_t valueLength = encoder.appendRange(first, last);
|
||||
encoder.prependVarNumber(valueLength);
|
||||
encoder.prependVarNumber(type);
|
||||
|
||||
return encoder.block();
|
||||
}
|
||||
};
|
||||
return encoder.block();
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/** @brief Create a TLV block copying TLV-VALUE from iterators.
|
||||
* @tparam Iterator an InputIterator dereferenceable to a 1-octet type; a faster implementation is
|
||||
* automatically selected for RandomAccessIterator
|
||||
* @param type TLV-TYPE number
|
||||
* @param first begin iterator
|
||||
* @param last past-the-end iterator
|
||||
* @sa prependBinaryBlock
|
||||
/**
|
||||
* @brief Create a TLV block copying TLV-VALUE from iterators.
|
||||
* @tparam Iterator an InputIterator dereferenceable to a 1-octet type; a faster implementation is
|
||||
* automatically selected for RandomAccessIterator
|
||||
* @param type TLV-TYPE number
|
||||
* @param first begin iterator
|
||||
* @param last past-the-end iterator
|
||||
* @sa prependBinaryBlock
|
||||
*/
|
||||
template<class Iterator>
|
||||
Block
|
||||
makeBinaryBlock(uint32_t type, Iterator first, Iterator last)
|
||||
{
|
||||
using BinaryBlockHelper = std::conditional_t<
|
||||
std::is_base_of_v<std::random_access_iterator_tag,
|
||||
typename std::iterator_traits<Iterator>::iterator_category>,
|
||||
detail::BinaryBlockFast<Iterator>,
|
||||
detail::BinaryBlockSlow<Iterator>>;
|
||||
|
||||
return BinaryBlockHelper::makeBlock(type, first, last);
|
||||
if constexpr (std::is_base_of_v<std::random_access_iterator_tag,
|
||||
typename std::iterator_traits<Iterator>::iterator_category>)
|
||||
return detail::makeBinaryBlockFast(type, first, last);
|
||||
else
|
||||
return detail::makeBinaryBlockSlow(type, first, last);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+48
-80
@@ -177,7 +177,7 @@ isCriticalType(uint32_t type) noexcept
|
||||
* @return true if number was successfully read from input, false otherwise
|
||||
*/
|
||||
template<typename Iterator>
|
||||
[[nodiscard]] bool
|
||||
[[nodiscard]] constexpr bool
|
||||
readVarNumber(Iterator& begin, Iterator end, uint64_t& number) noexcept;
|
||||
|
||||
/**
|
||||
@@ -194,7 +194,7 @@ readVarNumber(Iterator& begin, Iterator end, uint64_t& number) noexcept;
|
||||
* the TLV-TYPE is zero or larger than 2^32-1 (maximum allowed by the packet format).
|
||||
*/
|
||||
template<typename Iterator>
|
||||
[[nodiscard]] bool
|
||||
[[nodiscard]] constexpr bool
|
||||
readType(Iterator& begin, Iterator end, uint32_t& type) noexcept;
|
||||
|
||||
/**
|
||||
@@ -208,7 +208,7 @@ readType(Iterator& begin, Iterator end, uint32_t& type) noexcept;
|
||||
* @throw tlv::Error VAR-NUMBER cannot be read
|
||||
*/
|
||||
template<typename Iterator>
|
||||
uint64_t
|
||||
constexpr uint64_t
|
||||
readVarNumber(Iterator& begin, Iterator end);
|
||||
|
||||
/**
|
||||
@@ -224,13 +224,13 @@ readVarNumber(Iterator& begin, Iterator end);
|
||||
* the TLV-TYPE is zero or larger than 2^32-1 (maximum allowed by the packet format).
|
||||
*/
|
||||
template<typename Iterator>
|
||||
uint32_t
|
||||
constexpr uint32_t
|
||||
readType(Iterator& begin, Iterator end);
|
||||
|
||||
/**
|
||||
* @brief Get the number of bytes necessary to hold the value of @p number encoded as VAR-NUMBER.
|
||||
*/
|
||||
constexpr size_t
|
||||
[[nodiscard]] constexpr size_t
|
||||
sizeOfVarNumber(uint64_t number) noexcept;
|
||||
|
||||
/**
|
||||
@@ -254,13 +254,13 @@ writeVarNumber(std::ostream& os, uint64_t number);
|
||||
* If \p size differs from `std::distance(begin, end)`, tlv::Error exception will be thrown.
|
||||
*/
|
||||
template<typename Iterator>
|
||||
uint64_t
|
||||
constexpr uint64_t
|
||||
readNonNegativeInteger(size_t size, Iterator& begin, Iterator end);
|
||||
|
||||
/**
|
||||
* @brief Get the number of bytes necessary to hold the value of @p integer encoded as NonNegativeInteger.
|
||||
*/
|
||||
constexpr size_t
|
||||
[[nodiscard]] constexpr size_t
|
||||
sizeOfNonNegativeInteger(uint64_t integer) noexcept;
|
||||
|
||||
/**
|
||||
@@ -271,48 +271,35 @@ size_t
|
||||
writeNonNegativeInteger(std::ostream& os, uint64_t integer);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Inline definitions
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace detail {
|
||||
|
||||
/** @brief Function object to read a number from InputIterator.
|
||||
/**
|
||||
* @brief Determine whether to select the readNumber() implementation for ContiguousIterator.
|
||||
*
|
||||
* This is not a full ContiguousIterator detection implementation. It returns true for
|
||||
* the most common ContiguousIterator types used with TLV decoding function templates.
|
||||
*/
|
||||
template<typename Iterator>
|
||||
class ReadNumberSlow
|
||||
{
|
||||
public:
|
||||
constexpr bool
|
||||
operator()(size_t size, Iterator& begin, Iterator end, uint64_t& number) const noexcept
|
||||
{
|
||||
number = 0;
|
||||
size_t count = 0;
|
||||
for (; begin != end && count < size; ++begin, ++count) {
|
||||
number = (number << 8) | *begin;
|
||||
}
|
||||
return count == size;
|
||||
}
|
||||
};
|
||||
template<typename Iterator,
|
||||
typename DecayedIterator = std::decay_t<Iterator>,
|
||||
typename ValueType = typename std::iterator_traits<DecayedIterator>::value_type>
|
||||
inline constexpr bool IsContiguousIterator =
|
||||
(std::is_convertible_v<DecayedIterator, const ValueType*> ||
|
||||
std::is_convertible_v<DecayedIterator, typename std::basic_string<ValueType>::const_iterator> ||
|
||||
std::is_convertible_v<DecayedIterator, typename std::vector<ValueType>::const_iterator>) &&
|
||||
sizeof(ValueType) == 1 && !std::is_same_v<ValueType, bool>;
|
||||
|
||||
/** @brief Function object to read a number from ContiguousIterator.
|
||||
*/
|
||||
template<typename Iterator>
|
||||
class ReadNumberFast
|
||||
constexpr bool
|
||||
readNumber(size_t size, Iterator& begin, Iterator end, uint64_t& number) noexcept
|
||||
{
|
||||
public:
|
||||
constexpr bool
|
||||
operator()(size_t size, Iterator& begin, Iterator end, uint64_t& number) const noexcept
|
||||
{
|
||||
if constexpr (IsContiguousIterator<Iterator>) {
|
||||
// fast path
|
||||
if (begin + size > end) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (size) {
|
||||
case 1: {
|
||||
number = *begin;
|
||||
@@ -345,36 +332,21 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/** @brief Determine whether to select ReadNumber implementation for ContiguousIterator.
|
||||
*
|
||||
* This is not a full ContiguousIterator detection implementation. It returns true for the most
|
||||
* common ContiguousIterator types used with TLV decoding function templates.
|
||||
*/
|
||||
template<typename Iterator,
|
||||
typename DecayedIterator = std::decay_t<Iterator>,
|
||||
typename ValueType = typename std::iterator_traits<DecayedIterator>::value_type>
|
||||
constexpr bool
|
||||
shouldSelectContiguousReadNumber()
|
||||
{
|
||||
return (std::is_convertible_v<DecayedIterator, const ValueType*> ||
|
||||
std::is_convertible_v<DecayedIterator, typename std::basic_string<ValueType>::const_iterator> ||
|
||||
std::is_convertible_v<DecayedIterator, typename std::vector<ValueType>::const_iterator>) &&
|
||||
sizeof(ValueType) == 1 &&
|
||||
!std::is_same_v<ValueType, bool>;
|
||||
else {
|
||||
// slow path
|
||||
number = 0;
|
||||
size_t count = 0;
|
||||
for (; begin != end && count < size; ++begin, ++count) {
|
||||
number = (number << 8) | *begin;
|
||||
}
|
||||
return count == size;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Iterator>
|
||||
class ReadNumber : public std::conditional_t<shouldSelectContiguousReadNumber<Iterator>(),
|
||||
ReadNumberFast<Iterator>, ReadNumberSlow<Iterator>>
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<typename Iterator>
|
||||
bool
|
||||
constexpr bool
|
||||
readVarNumber(Iterator& begin, Iterator end, uint64_t& number) noexcept
|
||||
{
|
||||
if (begin == end)
|
||||
@@ -387,13 +359,13 @@ readVarNumber(Iterator& begin, Iterator end, uint64_t& number) noexcept
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t size = firstOctet == 253 ? 2 :
|
||||
firstOctet == 254 ? 4 : 8;
|
||||
return detail::ReadNumber<Iterator>()(size, begin, end, number);
|
||||
size_t len = firstOctet == 253 ? 2 :
|
||||
firstOctet == 254 ? 4 : 8;
|
||||
return detail::readNumber(len, begin, end, number);
|
||||
}
|
||||
|
||||
template<typename Iterator>
|
||||
bool
|
||||
constexpr bool
|
||||
readType(Iterator& begin, Iterator end, uint32_t& type) noexcept
|
||||
{
|
||||
uint64_t number = 0;
|
||||
@@ -407,24 +379,20 @@ readType(Iterator& begin, Iterator end, uint32_t& type) noexcept
|
||||
}
|
||||
|
||||
template<typename Iterator>
|
||||
uint64_t
|
||||
constexpr uint64_t
|
||||
readVarNumber(Iterator& begin, Iterator end)
|
||||
{
|
||||
if (begin == end) {
|
||||
NDN_THROW(Error("Empty buffer during TLV parsing"));
|
||||
}
|
||||
|
||||
uint64_t value = 0;
|
||||
bool isOk = readVarNumber(begin, end, value);
|
||||
uint64_t number = 0;
|
||||
bool isOk = readVarNumber(begin, end, number);
|
||||
if (!isOk) {
|
||||
NDN_THROW(Error("Insufficient data during TLV parsing"));
|
||||
}
|
||||
|
||||
return value;
|
||||
return number;
|
||||
}
|
||||
|
||||
template<typename Iterator>
|
||||
uint32_t
|
||||
constexpr uint32_t
|
||||
readType(Iterator& begin, Iterator end)
|
||||
{
|
||||
uint64_t type = readVarNumber(begin, end);
|
||||
@@ -471,15 +439,15 @@ writeVarNumber(std::ostream& os, uint64_t number)
|
||||
}
|
||||
|
||||
template<typename Iterator>
|
||||
uint64_t
|
||||
readNonNegativeInteger(size_t size, Iterator& begin, Iterator end)
|
||||
constexpr uint64_t
|
||||
readNonNegativeInteger(size_t len, Iterator& begin, Iterator end)
|
||||
{
|
||||
if (size != 1 && size != 2 && size != 4 && size != 8) {
|
||||
NDN_THROW(Error("Invalid length " + to_string(size) + " for NonNegativeInteger"));
|
||||
if (len != 1 && len != 2 && len != 4 && len != 8) {
|
||||
NDN_THROW(Error("Invalid NonNegativeInteger length " + to_string(len)));
|
||||
}
|
||||
|
||||
uint64_t number = 0;
|
||||
bool isOk = detail::ReadNumber<Iterator>()(size, begin, end, number);
|
||||
bool isOk = detail::readNumber(len, begin, end, number);
|
||||
if (!isOk) {
|
||||
NDN_THROW(Error("Insufficient data during NonNegativeInteger parsing"));
|
||||
}
|
||||
|
||||
+3
-12
@@ -34,33 +34,24 @@ namespace lp {
|
||||
*/
|
||||
namespace field_location_tags {
|
||||
|
||||
class Base
|
||||
{
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief A header field.
|
||||
*/
|
||||
class Header : public Base
|
||||
{
|
||||
};
|
||||
struct Header {};
|
||||
|
||||
/**
|
||||
* \brief The Fragment field.
|
||||
*/
|
||||
class Fragment : public Base
|
||||
{
|
||||
};
|
||||
struct Fragment {};
|
||||
|
||||
} // namespace field_location_tags
|
||||
|
||||
/**
|
||||
* \brief Concept check for NDNLPv2 fields.
|
||||
*/
|
||||
template<class X>
|
||||
template<typename X>
|
||||
struct Field
|
||||
{
|
||||
static_assert(std::is_base_of_v<field_location_tags::Base, typename X::FieldLocation>, "");
|
||||
static_assert(std::is_same_v<typename X::TlvType::value_type, uint32_t>, "");
|
||||
static_assert(std::is_same_v<typename X::IsRepeatable::value_type, bool>, "");
|
||||
static_assert(std::is_default_constructible_v<typename X::ValueType>, "");
|
||||
|
||||
+12
-25
@@ -30,44 +30,33 @@ namespace lp {
|
||||
|
||||
namespace {
|
||||
|
||||
template<typename TAG>
|
||||
int
|
||||
getLocationSortOrder() noexcept;
|
||||
|
||||
template<>
|
||||
constexpr int
|
||||
getLocationSortOrder<field_location_tags::Header>() noexcept
|
||||
template<typename Tag>
|
||||
constexpr int8_t
|
||||
getLocationSortOrder() noexcept
|
||||
{
|
||||
return 1;
|
||||
if constexpr (std::is_same_v<Tag, field_location_tags::Header>)
|
||||
return 1;
|
||||
if constexpr (std::is_same_v<Tag, field_location_tags::Fragment>)
|
||||
return 2;
|
||||
}
|
||||
|
||||
template<>
|
||||
constexpr int
|
||||
getLocationSortOrder<field_location_tags::Fragment>() noexcept
|
||||
struct FieldInfo
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
class FieldInfo
|
||||
{
|
||||
public:
|
||||
constexpr
|
||||
FieldInfo() noexcept = default;
|
||||
|
||||
explicit
|
||||
FieldInfo(uint32_t type) noexcept;
|
||||
|
||||
public:
|
||||
uint32_t tlvType = 0; ///< TLV-TYPE of the field; 0 if field does not exist
|
||||
bool isRecognized = false; ///< is this field known
|
||||
bool canIgnore = false; ///< can this unknown field be ignored
|
||||
bool isRepeatable = false; ///< is the field repeatable
|
||||
int locationSortOrder = getLocationSortOrder<field_location_tags::Header>(); ///< sort order of field_location_tag
|
||||
int8_t locationSortOrder = getLocationSortOrder<field_location_tags::Header>(); ///< sort order of field_location_tag
|
||||
};
|
||||
|
||||
class ExtractFieldInfo
|
||||
struct ExtractFieldInfo
|
||||
{
|
||||
public:
|
||||
using result_type = void;
|
||||
|
||||
template<typename T>
|
||||
@@ -115,7 +104,7 @@ Block
|
||||
Packet::wireEncode() const
|
||||
{
|
||||
// If no header or trailer, return bare network packet
|
||||
Block::element_container elements = m_wire.elements();
|
||||
auto elements = m_wire.elements();
|
||||
if (elements.size() == 1 && elements.front().type() == FragmentField::TlvType::value) {
|
||||
elements.front().parse();
|
||||
return elements.front().elements().front();
|
||||
@@ -169,9 +158,7 @@ Packet::wireDecode(const Block& wire)
|
||||
bool
|
||||
Packet::comparePos(uint32_t first, const Block& second) noexcept
|
||||
{
|
||||
FieldInfo firstInfo(first);
|
||||
FieldInfo secondInfo(second.type());
|
||||
return compareFieldSortOrder(firstInfo, secondInfo);
|
||||
return compareFieldSortOrder(FieldInfo(first), FieldInfo(second.type()));
|
||||
}
|
||||
|
||||
} // namespace lp
|
||||
|
||||
@@ -47,92 +47,52 @@ namespace net {
|
||||
|
||||
template<typename T>
|
||||
constexpr size_t
|
||||
getAttributeLength(const T* attr);
|
||||
|
||||
template<>
|
||||
constexpr size_t
|
||||
getAttributeLength(const nlattr* attr)
|
||||
getAttributeLength(const T* attr)
|
||||
{
|
||||
return attr->nla_len;
|
||||
}
|
||||
|
||||
template<>
|
||||
constexpr size_t
|
||||
getAttributeLength(const rtattr* attr)
|
||||
{
|
||||
return attr->rta_len;
|
||||
if constexpr (std::is_same_v<T, nlattr>)
|
||||
return attr->nla_len;
|
||||
if constexpr (std::is_same_v<T, rtattr>)
|
||||
return attr->rta_len;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr size_t
|
||||
getAttributeLengthAligned(const T* attr);
|
||||
|
||||
template<>
|
||||
constexpr size_t
|
||||
getAttributeLengthAligned(const nlattr* attr)
|
||||
getAttributeLengthAligned(const T* attr)
|
||||
{
|
||||
return NLA_ALIGN(attr->nla_len);
|
||||
}
|
||||
|
||||
template<>
|
||||
constexpr size_t
|
||||
getAttributeLengthAligned(const rtattr* attr)
|
||||
{
|
||||
return RTA_ALIGN(attr->rta_len);
|
||||
if constexpr (std::is_same_v<T, nlattr>)
|
||||
return NLA_ALIGN(attr->nla_len);
|
||||
if constexpr (std::is_same_v<T, rtattr>)
|
||||
return RTA_ALIGN(attr->rta_len);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr uint16_t
|
||||
getAttributeType(const T* attr);
|
||||
|
||||
template<>
|
||||
constexpr uint16_t
|
||||
getAttributeType(const nlattr* attr)
|
||||
uint16_t
|
||||
getAttributeType(const T* attr)
|
||||
{
|
||||
return attr->nla_type & NLA_TYPE_MASK;
|
||||
}
|
||||
|
||||
template<>
|
||||
constexpr uint16_t
|
||||
getAttributeType(const rtattr* attr)
|
||||
{
|
||||
return attr->rta_type;
|
||||
if constexpr (std::is_same_v<T, nlattr>)
|
||||
return attr->nla_type & NLA_TYPE_MASK;
|
||||
if constexpr (std::is_same_v<T, rtattr>)
|
||||
return attr->rta_type;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const uint8_t*
|
||||
getAttributeValue(const T* attr);
|
||||
|
||||
template<>
|
||||
inline const uint8_t*
|
||||
getAttributeValue(const nlattr* attr)
|
||||
getAttributeValue(const T* attr)
|
||||
{
|
||||
return reinterpret_cast<const uint8_t*>(attr) + NLA_HDRLEN;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline const uint8_t*
|
||||
getAttributeValue(const rtattr* attr)
|
||||
{
|
||||
return reinterpret_cast<const uint8_t*>(RTA_DATA(const_cast<rtattr*>(attr)));
|
||||
if constexpr (std::is_same_v<T, nlattr>)
|
||||
return reinterpret_cast<const uint8_t*>(attr) + NLA_HDRLEN;
|
||||
if constexpr (std::is_same_v<T, rtattr>)
|
||||
return reinterpret_cast<const uint8_t*>(RTA_DATA(const_cast<rtattr*>(attr)));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr size_t
|
||||
getAttributeValueLength(const T* attr);
|
||||
|
||||
template<>
|
||||
constexpr size_t
|
||||
getAttributeValueLength(const nlattr* attr)
|
||||
getAttributeValueLength(const T* attr)
|
||||
{
|
||||
return attr->nla_len - NLA_HDRLEN;
|
||||
}
|
||||
|
||||
template<>
|
||||
constexpr size_t
|
||||
getAttributeValueLength(const rtattr* attr)
|
||||
{
|
||||
return RTA_PAYLOAD(attr);
|
||||
if constexpr (std::is_same_v<T, nlattr>)
|
||||
return attr->nla_len - NLA_HDRLEN;
|
||||
if constexpr (std::is_same_v<T, rtattr>)
|
||||
return RTA_PAYLOAD(attr);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
* Copyright (c) 2013-2023 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -42,34 +42,30 @@ struct ReadVarNumberTest;
|
||||
template<>
|
||||
struct ReadVarNumberTest<1>
|
||||
{
|
||||
static const uint8_t WIRE[];
|
||||
static const uint64_t VALUE = 252;
|
||||
static constexpr uint8_t WIRE[] = {0xfc};
|
||||
static constexpr uint64_t VALUE = 252;
|
||||
};
|
||||
const uint8_t ReadVarNumberTest<1>::WIRE[] = {0xfc};
|
||||
|
||||
template<>
|
||||
struct ReadVarNumberTest<3>
|
||||
{
|
||||
static const uint8_t WIRE[];
|
||||
static const uint64_t VALUE = 253;
|
||||
static constexpr uint8_t WIRE[] = {0xfd, 0x00, 0xfd};
|
||||
static constexpr uint64_t VALUE = 253;
|
||||
};
|
||||
const uint8_t ReadVarNumberTest<3>::WIRE[] = {0xfd, 0x00, 0xfd};
|
||||
|
||||
template<>
|
||||
struct ReadVarNumberTest<5>
|
||||
{
|
||||
static const uint8_t WIRE[];
|
||||
static const uint64_t VALUE = 65536;
|
||||
static constexpr uint8_t WIRE[] = {0xfe, 0x00, 0x01, 0x00, 0x00};
|
||||
static constexpr uint64_t VALUE = 65536;
|
||||
};
|
||||
const uint8_t ReadVarNumberTest<5>::WIRE[] = {0xfe, 0x00, 0x01, 0x00, 0x00};
|
||||
|
||||
template<>
|
||||
struct ReadVarNumberTest<9>
|
||||
{
|
||||
static const uint8_t WIRE[];
|
||||
static const uint64_t VALUE = 4294967296;
|
||||
static constexpr uint8_t WIRE[] = {0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00};
|
||||
static constexpr uint64_t VALUE = 4294967296;
|
||||
};
|
||||
const uint8_t ReadVarNumberTest<9>::WIRE[] = {0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
template<size_t WIRE_SIZE, size_t ALIGNMENT_OFFSET>
|
||||
struct ReadVarNumberAlignTest : public ReadVarNumberTest<WIRE_SIZE>
|
||||
@@ -102,7 +98,7 @@ using ReadVarNumberTests = boost::mpl::vector<
|
||||
// It is recommended to run the benchmark multiple times and take the average.
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE(ReadVarNumber, Test, ReadVarNumberTests)
|
||||
{
|
||||
const int N_ITERATIONS = 100000000;
|
||||
constexpr int N_ITERATIONS = 100000000;
|
||||
|
||||
alignas(8) uint8_t buffer[16];
|
||||
static_assert(Test::AlignmentOffset::value + sizeof(Test::WIRE) <= sizeof(buffer), "");
|
||||
|
||||
@@ -169,7 +169,7 @@ BOOST_AUTO_TEST_CASE(FromType)
|
||||
BOOST_CHECK_EQUAL(b3.isValid(), false);
|
||||
BOOST_CHECK_EQUAL(b3.type(), tlv::Invalid);
|
||||
BOOST_CHECK_EXCEPTION(b3.size(), Block::Error, [] (const auto& e) {
|
||||
return e.what() == "Cannot determine size of invalid block"s;
|
||||
return e.what() == "Cannot determine size of invalid block"sv;
|
||||
});
|
||||
BOOST_CHECK_EQUAL(b3.hasValue(), false);
|
||||
BOOST_CHECK_EQUAL(b3.value_size(), 0);
|
||||
@@ -253,7 +253,7 @@ BOOST_AUTO_TEST_CASE(FromStream)
|
||||
|
||||
BOOST_CHECK(stream.eof());
|
||||
BOOST_CHECK_EXCEPTION(Block::fromStream(stream), tlv::Error, [] (const auto& e) {
|
||||
return e.what() == "Empty buffer during TLV parsing"s;
|
||||
return e.what() == "Insufficient data during TLV parsing"sv;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -315,7 +315,7 @@ BOOST_AUTO_TEST_CASE(FromStreamZeroLength)
|
||||
BOOST_CHECK(b3.value() == nullptr);
|
||||
|
||||
BOOST_CHECK_EXCEPTION(Block::fromStream(stream), tlv::Error, [] (const auto& e) {
|
||||
return e.what() == "Empty buffer during TLV parsing"s;
|
||||
return e.what() == "Insufficient data during TLV parsing"sv;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -331,7 +331,7 @@ BOOST_AUTO_TEST_CASE(FromStreamPacketTooLarge)
|
||||
stream.seekg(0);
|
||||
|
||||
BOOST_CHECK_EXCEPTION(Block::fromStream(stream), tlv::Error, [] (const auto& e) {
|
||||
return e.what() == "TLV-LENGTH from stream exceeds limit"s;
|
||||
return e.what() == "TLV-LENGTH from stream exceeds limit"sv;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -447,12 +447,12 @@ BOOST_AUTO_TEST_CASE(BlockFromValue)
|
||||
{
|
||||
Block b1(301);
|
||||
BOOST_CHECK_EXCEPTION(b1.blockFromValue(), Block::Error, [] (const auto& e) {
|
||||
return e.what() == "Cannot construct block from empty TLV-VALUE"s;
|
||||
return e.what() == "Cannot construct block from empty TLV-VALUE"sv;
|
||||
});
|
||||
|
||||
Block b2(302, std::make_shared<Buffer>());
|
||||
BOOST_CHECK_EXCEPTION(b2.blockFromValue(), Block::Error, [] (const auto& e) {
|
||||
return e.what() == "Cannot construct block from empty TLV-VALUE"s;
|
||||
return e.what() == "Cannot construct block from empty TLV-VALUE"sv;
|
||||
});
|
||||
|
||||
b1.encode();
|
||||
@@ -491,7 +491,7 @@ BOOST_AUTO_TEST_CASE(Parse)
|
||||
|
||||
BOOST_CHECK(data.get(0x15) == data.elements().at(2));
|
||||
BOOST_CHECK_EXCEPTION(data.get(0x01), Block::Error, [] (const auto& e) {
|
||||
return e.what() == "No sub-element of type 1 found in block of type 6"s;
|
||||
return e.what() == "No sub-element of type 1 found in block of type 6"sv;
|
||||
});
|
||||
|
||||
BOOST_CHECK(data.find(0x15) == data.elements_begin() + 2);
|
||||
@@ -503,7 +503,7 @@ BOOST_AUTO_TEST_CASE(Parse)
|
||||
};
|
||||
Block bad(MALFORMED);
|
||||
BOOST_CHECK_EXCEPTION(bad.parse(), Block::Error, [] (const auto& e) {
|
||||
return e.what() == "TLV-LENGTH of sub-element of type 7 exceeds TLV-VALUE boundary of parent block"s;
|
||||
return e.what() == "TLV-LENGTH of sub-element of type 7 exceeds TLV-VALUE boundary of parent block"sv;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -59,11 +59,9 @@ using ArrayStream = boost::iostreams::stream<boost::iostreams::array_source>;
|
||||
using StreamIterator = std::istream_iterator<uint8_t>;
|
||||
|
||||
#define ASSERT_READ_NUMBER_IS_FAST(T) \
|
||||
static_assert(std::is_base_of_v<detail::ReadNumberFast<T>, detail::ReadNumber<T>>, \
|
||||
# T " should use ReadNumberFast")
|
||||
static_assert(detail::IsContiguousIterator<T>, #T " is not fast")
|
||||
#define ASSERT_READ_NUMBER_IS_SLOW(T) \
|
||||
static_assert(std::is_base_of_v<detail::ReadNumberSlow<T>, detail::ReadNumber<T>>, \
|
||||
# T " should use ReadNumberSlow")
|
||||
static_assert(!detail::IsContiguousIterator<T>, #T " is not slow")
|
||||
|
||||
ASSERT_READ_NUMBER_IS_FAST(const uint8_t*);
|
||||
ASSERT_READ_NUMBER_IS_FAST(uint8_t*);
|
||||
@@ -80,6 +78,8 @@ ASSERT_READ_NUMBER_IS_FAST(Uint8Array::const_iterator);
|
||||
ASSERT_READ_NUMBER_IS_FAST(Uint8Array::iterator);
|
||||
using CharArray = std::array<char, 87>;
|
||||
ASSERT_READ_NUMBER_IS_FAST(CharArray::iterator);
|
||||
ASSERT_READ_NUMBER_IS_FAST(span<const uint8_t>::iterator);
|
||||
ASSERT_READ_NUMBER_IS_FAST(span<uint8_t>::iterator);
|
||||
ASSERT_READ_NUMBER_IS_FAST(std::string::const_iterator);
|
||||
ASSERT_READ_NUMBER_IS_FAST(std::string::iterator);
|
||||
ASSERT_READ_NUMBER_IS_FAST(Buffer::const_iterator);
|
||||
|
||||
Reference in new issue
Block a user