xaizek / tos (License: GPLv3 only) (since 2018-12-07)
This is an alternative version of sources presented as part of Write Your Own OS video tutorial by Viktor Engelmann.
<root> / src / utils / span.hpp (17d9339adbb963fd88a336c6b3ee7bfaba5adac1) (2,757B) (mode 100644) [raw]
#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__
Hints

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