#ifndef TOS__UTILS__SPAN_HPP__
#define TOS__UTILS__SPAN_HPP__
#include <cstddef>
#include <cstdint>
#include <algorithm>
#include <type_traits>
template <typename T>
class span
{
public:
constexpr span() noexcept
: ptr(nullptr), count(0)
{
}
constexpr span(T ptr[], std::ptrdiff_t count) noexcept
: ptr(ptr), count(count)
{
}
template <std::size_t N>
constexpr span(T (&arr)[N]) noexcept
: ptr(arr), count(N)
{
}
template <class U,
typename std::enable_if<
std::is_convertible<U(*)[], T(*)[]>::value, int>::type = 0>
constexpr span(const span<U> &rhs) noexcept
: ptr(rhs.data()), count(rhs.size())
{
}
public:
constexpr T * data() const noexcept
{
return ptr;
}
constexpr std::ptrdiff_t size() const noexcept
{
return count;
}
constexpr span before(std::ptrdiff_t n) const noexcept
{
return span(ptr, count - (n > count ? count : n));
}
constexpr span after(std::ptrdiff_t n) const noexcept
{
return span(ptr + (n > count ? count : n),
count - (n > count ? count : n));
}
constexpr span first(std::ptrdiff_t n) const noexcept
{
return span(ptr, n);
}
constexpr span last(std::ptrdiff_t n) const noexcept
{
return span(ptr + (count - n), n);
}
constexpr span subspan(std::ptrdiff_t offset, std::ptrdiff_t count) const
{
return span(ptr + offset, count);
}
constexpr T & operator[](std::ptrdiff_t idx) const noexcept
{
return ptr[idx];
}
constexpr T & operator()(std::ptrdiff_t idx) const noexcept
{
return ptr[idx];
}
constexpr T * begin() const noexcept
{
return ptr;
}
constexpr const T * cbegin() const noexcept
{
return ptr;
}
constexpr T * end() const noexcept
{
return ptr + count;
}
constexpr const T * cend() const noexcept
{
return ptr + count;
}
private:
T *ptr;
std::ptrdiff_t count;
};
template <typename T, std::ptrdiff_t N>
constexpr span<const std::uint8_t>
as_bytes(T (&arr)[N]) noexcept
{
return span<const std::uint8_t> {
reinterpret_cast<const std::uint8_t *>(arr), N
};
}
template <typename T>
constexpr span<const std::uint8_t>
as_bytes(span<T> s) noexcept
{
return span<const std::uint8_t> {
reinterpret_cast<const std::uint8_t *>(s.data()), s.size()
};
}
template <typename T>
constexpr span<std::uint8_t>
as_writable_bytes(T &d) noexcept
{
return span<std::uint8_t> {
reinterpret_cast<std::uint8_t *>(&d), sizeof(d)
};
}
#endif // TOS__UTILS__SPAN_HPP__
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"
Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/tos
Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/tos
You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a
pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master