<commit_before>// This file is part of Poseidon.
// Copyleft 2022, LH_Mouse. All wrongs reserved.

#ifndef POSEIDON_CORE_CHARBUF_256_
#define POSEIDON_CORE_CHARBUF_256_

#include "../fwd.hpp"

namespace poseidon {

// This class provides 256-byte storage for temporary use.
class charbuf_256
  {
  private:
    char m_data[256];

  public:
    // Constructs a null-terminated string of zero characters.
    explicit
    charbuf_256() noexcept
      {
        this->m_data[0] = 0;
      }

    // Constructs a null-terminated string.
    // This constructor is not explicit as it doesn't allocate memory.
    charbuf_256(const char* str_opt)
      {
        const char* str = str_opt;
        if(!str)
          str = "";

        size_t len = ::std::strlen(str);
        if(len >= 256)
          ::rocket::sprintf_and_throw<::std::length_error>(
              "charbuf_256: string `%s` (length `%lld`) too long",
              str, (long long) len);

        ::std::memcpy(this->m_data, str, len + 1);
      }

  public:
    // Swaps two buffers.
    charbuf_256&
    swap(charbuf_256& other) noexcept
      {
        char temp[256];
        ::std::memcpy(temp, other.m_data, sizeof(temp));
        ::std::memcpy(other.m_data, this->m_data, sizeof(temp));
        ::std::memcpy(this->m_data, temp, sizeof(temp));
        return *this;
      }

    // Performs 3-way comparison of two buffers.
    int
    compare(const charbuf_256& other) const noexcept
      {
        return ::std::strcmp(this->m_data, other.m_data);
      }

    int
    compare(const char* other) const noexcept
      {
        return ::std::strcmp(this->m_data, other);
      }

    // Returns a pointer to internal storage so a buffer can be passed as
    // an argument for `char*`.
    constexpr operator
    const char*() const noexcept
      { return this->m_data;  }

    operator
    char*() noexcept
      { return this->m_data;  }
  };

inline
void
swap(charbuf_256& lhs, charbuf_256& rhs) noexcept
  {
    lhs.swap(rhs);
  }

inline
bool
operator==(const charbuf_256& lhs, const charbuf_256& rhs) noexcept
  {
    return ::std::strcmp(lhs, rhs) == 0;
  }

inline
bool
operator==(const char* lhs, const charbuf_256& rhs) noexcept
  {
    return ::std::strcmp(lhs, rhs) == 0;
  }

inline
bool
operator==(const charbuf_256& lhs, const char* rhs) noexcept
  {
    return ::std::strcmp(lhs, rhs) == 0;
  }

inline<commit_msg>charbuf_256: Make constructors non-explicit, and add `operator<<`<commit_after>// This file is part of Poseidon.
// Copyleft 2022, LH_Mouse. All wrongs reserved.

#ifndef POSEIDON_CORE_CHARBUF_256_
#define POSEIDON_CORE_CHARBUF_256_

#include "../fwd.hpp"

namespace poseidon {

// This class provides 256-byte storage for temporary use.
class charbuf_256
  {
  private:
    char m_data[256];

  public:
    // Constructs a null-terminated string of zero characters.
    // This constructor is not explicit as it doesn't allocate memory.
    charbuf_256() noexcept
      {
        this->m_data[0] = 0;
      }

    // Constructs a null-terminated string.
    // This constructor is not explicit as it doesn't allocate memory.
    charbuf_256(const char* str_opt)
      {
        const char* str = str_opt;
        if(!str)
          str = "";

        size_t len = ::std::strlen(str);
        if(len >= 256)
          ::rocket::sprintf_and_throw<::std::length_error>(
              "charbuf_256: string `%s` (length `%lld`) too long",
              str, (long long) len);

        ::std::memcpy(this->m_data, str, len + 1);
      }

  public:
    // Swaps two buffers.
    charbuf_256&
    swap(charbuf_256& other) noexcept
      {
        char temp[256];
        ::std::memcpy(temp, other.m_data, sizeof(temp));
        ::std::memcpy(other.m_data, this->m_data, sizeof(temp));
        ::std::memcpy(this->m_data, temp, sizeof(temp));
        return *this;
      }

    // Performs 3-way comparison of two buffers.
    int
    compare(const charbuf_256& other) const noexcept
      {
        return ::std::strcmp(this->m_data, other.m_data);
      }

    int
    compare(const char* other) const noexcept
      {
        return ::std::strcmp(this->m_data, other);
      }

    // Returns a pointer to internal storage so a buffer can be passed as
    // an argument for `char*`.
    constexpr operator
    const char*() const noexcept
      { return this->m_data;  }

    operator
    char*() noexcept
      { return this->m_data;  }
  };

inline
void
swap(charbuf_256& lhs, charbuf_256& rhs) noexcept
  {
    lhs.swap(rhs);
  }

inline
tinyfmt&
operator<<(tinyfmt& fmt, const charbuf_256& cbuf)
  {
    return fmt << (const char*) cbuf;
  }

inline
bool
operator==(const charbuf_256& lhs, const charbuf_256& rhs) noexcept
  {
    return ::std::strcmp(lhs, rhs) == 0;
  }

inline
bool
operator==(const char* lhs, const charbuf_256& rhs) noexcept
  {
    return ::std::strcmp(lhs, rhs) == 0;
  }

inline
bool
operator==(const charbuf_256& lhs, const char* rhs) noexcept
  {
    return ::std::strcmp(lhs, rhs) == 0;
  }

inline
{'fraction_non_alphanumeric': 0.1259200318281281, 'fraction_numerical': 0.028247463696041378, 'mean_word_length': 2.5939957112223015, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3709996', 'n_tokens_mistral': 1803, 'n_tokens_neox': 1692, 'n_words': 454}