mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-07 13:03:45 +02:00
File this idea away.
This commit is contained in:
parent
1f85b0402e
commit
afa01074c5
1 changed files with 176 additions and 0 deletions
176
attic/BP.hpp
Normal file
176
attic/BP.hpp
Normal file
|
@ -0,0 +1,176 @@
|
|||
/*
|
||||
* Copyright (c)2013-2020 ZeroTier, Inc.
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file in the project's root directory.
|
||||
*
|
||||
* Change Date: 2024-01-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2.0 of the Apache License.
|
||||
*/
|
||||
/****/
|
||||
|
||||
#ifndef ZT_BP_HPP
|
||||
#define ZT_BP_HPP
|
||||
|
||||
#include "Constants.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
/**
|
||||
* A C-like pointer to a byte array with static bounds checking whenever possible.
|
||||
*
|
||||
* This fills the niche in between Buf and a naked C pointer and behaves like a C pointer
|
||||
* annotated with a length that is statically checked at compile time. It should have no
|
||||
* runtime overhead at all.
|
||||
*
|
||||
* - Explicit or implicit casts are supported to pointers to smaller but not larger arrays
|
||||
* - A templated slice() method (analogous to Go slices) allows getting subset arrays
|
||||
* - A templated at() method allows bounds checked access to indices known at compile time
|
||||
* - Copy and assignment from larger or equal sized arrays, but not smaller
|
||||
* - NULL pointers are explicitly not allowed, so a naked pointer must still be used in that case
|
||||
*
|
||||
* Note that the [] operator for dynamic access is NOT bounds checked as this would add
|
||||
* runtime overhead that is not desirable where this is used. The goal here is to keep
|
||||
* C performance while being safer to the extent that C++ allows.
|
||||
*
|
||||
* @tparam S Size of memory to which this pointer must point
|
||||
*/
|
||||
template<unsigned int S>
|
||||
class BP
|
||||
{
|
||||
public:
|
||||
typedef uint8_t * iterator;
|
||||
typedef const uint8_t * const_iterator;
|
||||
|
||||
explicit ZT_INLINE BP(void *const bytes) : p(reinterpret_cast<uint8_t *>(bytes)) {}
|
||||
|
||||
template<unsigned int CS>
|
||||
ZT_INLINE BP(BP<CS> &b) noexcept :
|
||||
p(b.p)
|
||||
{
|
||||
static_assert(CS <= S,"attempt to copy byte pointer from one of smaller size");
|
||||
}
|
||||
|
||||
template<unsigned int CS>
|
||||
ZT_INLINE BP &operator=(BP<CS> &b)
|
||||
{
|
||||
static_assert(CS <= S,"attempt to assign byte pointer from one of smaller size");
|
||||
p = b.p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<unsigned int CS>
|
||||
ZT_INLINE operator BP<CS>() noexcept // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
|
||||
{
|
||||
static_assert(CS <= S,"attempt to cast byte pointer to larger size");
|
||||
return BP<CS>(p);
|
||||
}
|
||||
|
||||
ZT_INLINE uint8_t &operator[](const unsigned int i) noexcept
|
||||
{
|
||||
return p[i];
|
||||
}
|
||||
ZT_INLINE uint8_t operator[](const unsigned int i) const noexcept
|
||||
{
|
||||
return p[i];
|
||||
}
|
||||
template<typename I>
|
||||
ZT_INLINE uint8_t *operator+(const I i) noexcept
|
||||
{
|
||||
return p + i;
|
||||
}
|
||||
template<typename I>
|
||||
ZT_INLINE const uint8_t *operator+(const I i) const noexcept
|
||||
{
|
||||
return p + i;
|
||||
}
|
||||
|
||||
ZT_INLINE uint8_t &operator*() noexcept
|
||||
{
|
||||
static_assert(S > 0,"attempt to access empty array");
|
||||
return *p;
|
||||
}
|
||||
ZT_INLINE uint8_t operator*() const noexcept
|
||||
{
|
||||
static_assert(S > 0,"attempt to access empty array");
|
||||
return *p;
|
||||
}
|
||||
|
||||
template<unsigned int I>
|
||||
ZT_INLINE uint8_t &at() noexcept
|
||||
{
|
||||
static_assert(I < S,"static access beyond end of byte pointer");
|
||||
return p[I];
|
||||
}
|
||||
template<unsigned int I>
|
||||
ZT_INLINE uint8_t at() const noexcept
|
||||
{
|
||||
static_assert(I < S,"static access beyond end of byte pointer");
|
||||
return p[I];
|
||||
}
|
||||
|
||||
template<unsigned int RS,unsigned int RE>
|
||||
ZT_INLINE BP<RE - RS> &slice() noexcept
|
||||
{
|
||||
static_assert(RE > RS,"slice must end after it begins");
|
||||
static_assert(RE <= S,"slice ends after byte array end");
|
||||
return reinterpret_cast< BP<RE - RS> >(*this);
|
||||
}
|
||||
|
||||
template<unsigned int RS,unsigned int RE>
|
||||
ZT_INLINE const BP<RE - RS> &slice() const noexcept
|
||||
{
|
||||
static_assert(RE > RS,"slice must end after it begins");
|
||||
static_assert(RE <= S,"slice ends after byte array end");
|
||||
return reinterpret_cast< BP<RE - RS> >(*this);
|
||||
}
|
||||
|
||||
template<unsigned int F>
|
||||
ZT_INLINE BP<S - F> &from() noexcept
|
||||
{
|
||||
static_assert(F < S,"attempt to get array from beyond bounds");
|
||||
return reinterpret_cast< BP<S - F> >(*this);
|
||||
}
|
||||
template<unsigned int F>
|
||||
ZT_INLINE const BP<S - F> &from() const noexcept
|
||||
{
|
||||
static_assert(F < S,"attempt to get array from beyond bounds");
|
||||
return reinterpret_cast< BP<S - F> >(*this);
|
||||
}
|
||||
|
||||
ZT_INLINE iterator begin() noexcept { return p; }
|
||||
ZT_INLINE iterator end() noexcept { return p + S; }
|
||||
ZT_INLINE const_iterator begin() const noexcept { return p; }
|
||||
ZT_INLINE const_iterator end() const noexcept { return p + S; }
|
||||
|
||||
static constexpr unsigned int size() noexcept { return S; }
|
||||
|
||||
template<unsigned int CS>
|
||||
ZT_INLINE bool operator==(const BP<CS> &b) const noexcept { return p == b.p; }
|
||||
template<unsigned int CS>
|
||||
ZT_INLINE bool operator!=(const BP<CS> &b) const noexcept { return p != b.p; }
|
||||
template<unsigned int CS>
|
||||
ZT_INLINE bool operator<(const BP<CS> &b) const noexcept { return p < b.p; }
|
||||
template<unsigned int CS>
|
||||
ZT_INLINE bool operator>(const BP<CS> &b) const noexcept { return p > b.p; }
|
||||
template<unsigned int CS>
|
||||
ZT_INLINE bool operator<=(const BP<CS> &b) const noexcept { return p <= b.p; }
|
||||
template<unsigned int CS>
|
||||
ZT_INLINE bool operator>=(const BP<CS> &b) const noexcept { return p >= b.p; }
|
||||
|
||||
ZT_INLINE bool operator==(const void *const b) const noexcept { return p == reinterpret_cast<const uint8_t *>(b); }
|
||||
ZT_INLINE bool operator!=(const void *const b) const noexcept { return p != reinterpret_cast<const uint8_t *>(b); }
|
||||
ZT_INLINE bool operator<(const void *const b) const noexcept { return p < reinterpret_cast<const uint8_t *>(b); }
|
||||
ZT_INLINE bool operator>(const void *const b) const noexcept { return p > reinterpret_cast<const uint8_t *>(b); }
|
||||
ZT_INLINE bool operator<=(const void *const b) const noexcept { return p <= reinterpret_cast<const uint8_t *>(b); }
|
||||
ZT_INLINE bool operator>=(const void *const b) const noexcept { return p >= reinterpret_cast<const uint8_t *>(b); }
|
||||
|
||||
private:
|
||||
uint8_t *const p;
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
#endif
|
Loading…
Add table
Reference in a new issue