flatten 20260225
This commit is contained in:
23
tjp/core/const_expr/Str+IO.hpp
Executable file
23
tjp/core/const_expr/Str+IO.hpp
Executable file
@@ -0,0 +1,23 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
namespace tjp::core::const_expr {
|
||||
|
||||
template<size_t N>
|
||||
std::ostream &operator <<(std::ostream &o, const Str<N> &v)
|
||||
{
|
||||
return o << (std::string_view)(v);
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream &operator <<(std::ostream &o, const StrView &v)
|
||||
{
|
||||
return o << (std::string_view)(v);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
96
tjp/core/const_expr/Str.hpp
Executable file
96
tjp/core/const_expr/Str.hpp
Executable file
@@ -0,0 +1,96 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string_view>
|
||||
|
||||
namespace tjp::core::const_expr {
|
||||
|
||||
// Note: rename this MutableStrView - or make different types - something
|
||||
struct StrView
|
||||
{
|
||||
char *v;
|
||||
size_t len;
|
||||
|
||||
constexpr StrView(char *v_, size_t len_) :
|
||||
v(v_), len(len_)
|
||||
{}
|
||||
|
||||
constexpr StrView(const char *v_, size_t len_) :
|
||||
v(const_cast<char *>(v_)), len(len_)
|
||||
{}
|
||||
|
||||
constexpr StrView(const std::string_view &v_) :
|
||||
v((char *)v_.data()), len(v_.size())
|
||||
{}
|
||||
|
||||
constexpr auto *data() { return v; }
|
||||
constexpr auto *begin() const { return v; }
|
||||
constexpr auto *end() const { return begin() + size(); }
|
||||
constexpr auto *begin() { return v; }
|
||||
constexpr auto *end() { return begin() + size(); }
|
||||
constexpr size_t size() { return len; }
|
||||
constexpr size_t size() const { return len; }
|
||||
|
||||
constexpr void set(const size_t i, const char c) { v[i] = c; }
|
||||
constexpr char operator[](const size_t i) const { return v[i]; }
|
||||
|
||||
constexpr operator std::string_view() const
|
||||
{
|
||||
return std::string_view(v, len);
|
||||
}
|
||||
} ;
|
||||
|
||||
template<size_t N>
|
||||
struct Str {
|
||||
char v[N];
|
||||
|
||||
constexpr Str(const char *s) :
|
||||
v{0}
|
||||
{
|
||||
for (auto i=0; i<N; ++i)
|
||||
v[i] = s[i];
|
||||
}
|
||||
|
||||
constexpr Str() : v{0}
|
||||
{
|
||||
}
|
||||
|
||||
constexpr auto *data() const { return v; }
|
||||
constexpr auto *begin() const { return &v[0]; }
|
||||
constexpr auto *end() const { return begin() + size(); }
|
||||
constexpr auto *begin() { return &v[0]; }
|
||||
constexpr auto *end() { return begin() + size(); }
|
||||
constexpr size_t size() const { return N; }
|
||||
|
||||
constexpr void set(const size_t i, const char c) { v[i] = c; }
|
||||
constexpr char operator[](const size_t i) const { return v[i]; }
|
||||
|
||||
constexpr operator std::string_view() const
|
||||
{
|
||||
return std::string_view(begin(), size());
|
||||
}
|
||||
|
||||
constexpr operator StrView()
|
||||
{
|
||||
return StrView(begin(), size());
|
||||
}
|
||||
|
||||
constexpr operator const StrView() const
|
||||
{
|
||||
return StrView((char *)begin(), size());
|
||||
}
|
||||
} ;
|
||||
|
||||
template<size_t N>
|
||||
constexpr bool operator ==(const Str<N> &lhs, const char *rhs)
|
||||
{
|
||||
return (std::string_view)lhs == rhs;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#include "Str+IO.hpp"
|
||||
27
tjp/core/const_expr/_tests/Str.cpp
Executable file
27
tjp/core/const_expr/_tests/Str.cpp
Executable file
@@ -0,0 +1,27 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#include <tjp/core/const_expr/concat.hpp>
|
||||
#include <tjp/core/const_expr/Str.hpp>
|
||||
|
||||
#include <tjp/core/testing/catch.hpp>
|
||||
|
||||
namespace tjp::core::const_expr {
|
||||
namespace {
|
||||
|
||||
|
||||
constexpr bool str_is_const_expr()
|
||||
{
|
||||
char source[] = "a> b> c";
|
||||
|
||||
auto result = StrView(source, 7);
|
||||
result.set(0, 'q');
|
||||
|
||||
return result[0] == 'q';
|
||||
}
|
||||
|
||||
static_assert(str_is_const_expr(), "str_is_const_expr should be constexpr");
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
39
tjp/core/const_expr/_tests/concat.cpp
Executable file
39
tjp/core/const_expr/_tests/concat.cpp
Executable file
@@ -0,0 +1,39 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#include <tjp/core/const_expr/concat.hpp>
|
||||
#include <tjp/core/const_expr/Str.hpp>
|
||||
|
||||
#include <tjp/core/testing/catch.hpp>
|
||||
|
||||
namespace tjp::core::const_expr {
|
||||
namespace {
|
||||
|
||||
SCENARIO("core::const_expr::concat")
|
||||
{
|
||||
WHEN("two strings")
|
||||
{
|
||||
constexpr std::string_view a("a");
|
||||
constexpr std::string_view b("b");
|
||||
static_assert(a == "a");
|
||||
static_assert(b == "b");
|
||||
|
||||
constexpr Str<2> ab("ab");
|
||||
static_assert((std::string_view)ab == "ab");
|
||||
|
||||
constexpr auto NULL_CHAR = 1;
|
||||
constexpr auto abc = concat("ab", "c");
|
||||
static_assert(abc.size() == 3+NULL_CHAR);
|
||||
constexpr Str<abc.size()-NULL_CHAR> abcs(abc.data());
|
||||
static_assert((std::string_view)abcs == "abc");
|
||||
|
||||
REQUIRE(ab == "ab");
|
||||
REQUIRE(abcs == "abc");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
24
tjp/core/const_expr/_tests/length.cpp
Executable file
24
tjp/core/const_expr/_tests/length.cpp
Executable file
@@ -0,0 +1,24 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#include <tjp/core/const_expr/length.hpp>
|
||||
#include <tjp/core/const_expr/Str.hpp>
|
||||
|
||||
#include <tjp/core/testing/catch.hpp>
|
||||
|
||||
namespace tjp::core::const_expr {
|
||||
namespace {
|
||||
|
||||
SCENARIO("core::const_expr::length")
|
||||
{
|
||||
WHEN("string")
|
||||
{
|
||||
static_assert(length("abc") == 3);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
99
tjp/core/const_expr/_tests/remove_char.cpp
Normal file
99
tjp/core/const_expr/_tests/remove_char.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#include <tjp/core/const_expr/remove_char.hpp>
|
||||
#include <tjp/core/testing/catch.hpp>
|
||||
|
||||
namespace tjp::core::const_expr {
|
||||
namespace {
|
||||
|
||||
constexpr bool remove_char_constexpr_check()
|
||||
{
|
||||
char source[] = "a_b_c";
|
||||
char result[] = {0, 0, 0, 0, 0};
|
||||
|
||||
remove_char(
|
||||
StrView(source, 5),
|
||||
StrView(result, 5),
|
||||
'_'
|
||||
);
|
||||
|
||||
return
|
||||
result[0] == 'a' &&
|
||||
result[1] == 'b' &&
|
||||
result[2] == 'c';
|
||||
}
|
||||
|
||||
constexpr bool remove_second_of_char_2_constexpr_check()
|
||||
{
|
||||
char source[] = "a> b> c";
|
||||
char result[] = {0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
remove_second_of_char_2(
|
||||
StrView(source, 7),
|
||||
StrView(result, 7),
|
||||
"> "
|
||||
);
|
||||
|
||||
return
|
||||
result[0] == 'a' &&
|
||||
result[1] == '>' &&
|
||||
result[2] == 'b' &&
|
||||
result[3] == '>' &&
|
||||
result[4] == 'c';
|
||||
}
|
||||
|
||||
static_assert(remove_char_constexpr_check(), "remove_char should be constexpr");
|
||||
static_assert(
|
||||
remove_second_of_char_2_constexpr_check(),
|
||||
"remove_second_of_char_2 should be constexpr"
|
||||
);
|
||||
|
||||
SCENARIO("core::const_expr::remove_char")
|
||||
{
|
||||
WHEN("removing a single character from a string")
|
||||
{
|
||||
char source[] = "a_b_c";
|
||||
char result[] = {0, 0, 0, 0, 0};
|
||||
|
||||
remove_char(
|
||||
StrView(source, 5),
|
||||
StrView(result, 5),
|
||||
'_'
|
||||
);
|
||||
|
||||
REQUIRE(std::string_view(result, 3) == "abc");
|
||||
}
|
||||
|
||||
WHEN("removing the second character of a two-character sequence")
|
||||
{
|
||||
char source[] = "a> b> c";
|
||||
char result[] = {0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
remove_second_of_char_2(
|
||||
StrView(source, 7),
|
||||
StrView(result, 7),
|
||||
"> "
|
||||
);
|
||||
|
||||
REQUIRE(std::string_view(result, 5) == "a>b>c");
|
||||
}
|
||||
|
||||
WHEN("input is empty")
|
||||
{
|
||||
char source[] = "";
|
||||
char result[] = {'x'};
|
||||
|
||||
remove_second_of_char_2(
|
||||
StrView(source, 0),
|
||||
StrView(result, 1),
|
||||
"> "
|
||||
);
|
||||
|
||||
REQUIRE(result[0] == 'x');
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
26
tjp/core/const_expr/concat.hpp
Executable file
26
tjp/core/const_expr/concat.hpp
Executable file
@@ -0,0 +1,26 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace tjp::core::const_expr {
|
||||
|
||||
template<size_t N, size_t M>
|
||||
constexpr auto concat(const char (&a)[N], const char (&b)[M]) {
|
||||
std::array<char, N + M - 1> result{}; // -1 because we don't need two null terminators
|
||||
|
||||
for (size_t i = 0; i < N - 1; ++i) {
|
||||
result[i] = a[i];
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < M; ++i) {
|
||||
result[N - 1 + i] = b[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
35
tjp/core/const_expr/count_char.hpp
Executable file
35
tjp/core/const_expr/count_char.hpp
Executable file
@@ -0,0 +1,35 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace tjp::core::const_expr {
|
||||
|
||||
[[nodiscard]]
|
||||
inline constexpr auto count_char(const StrView &s, const char v)
|
||||
{
|
||||
size_t num = 0;
|
||||
for (auto &c : s)
|
||||
{
|
||||
if (c == v)
|
||||
++num;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
inline constexpr auto count_char(const StrView &s, const char v[2])
|
||||
{
|
||||
size_t num = 0;
|
||||
for (size_t i=1; i<s.size(); ++i)
|
||||
{
|
||||
if (s[i-1] == v[0] && s[i] == v[1])
|
||||
++num;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
21
tjp/core/const_expr/length.hpp
Executable file
21
tjp/core/const_expr/length.hpp
Executable file
@@ -0,0 +1,21 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
namespace tjp::core::const_expr {
|
||||
|
||||
[[nodiscard]]
|
||||
inline constexpr auto length(const char *s)
|
||||
{
|
||||
size_t size = 0;
|
||||
while (*s++)
|
||||
size++;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
40
tjp/core/const_expr/remove_char.hpp
Executable file
40
tjp/core/const_expr/remove_char.hpp
Executable file
@@ -0,0 +1,40 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Str.hpp"
|
||||
|
||||
namespace tjp::core::const_expr {
|
||||
|
||||
[[nodiscard]]
|
||||
inline constexpr auto remove_char(const StrView &s, StrView result, const char v)
|
||||
{
|
||||
int i = 0;
|
||||
for (auto &c : s)
|
||||
{
|
||||
if (c != v)
|
||||
result.set(i++, c);
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
inline constexpr auto remove_second_of_char_2(const StrView &s, StrView result, const char v[2])
|
||||
{
|
||||
if (result.size() == 0 || s.size() == 0)
|
||||
return;
|
||||
|
||||
size_t r = 0;
|
||||
result.set(r++, s[0]);
|
||||
for (size_t i=1; i<s.size(); ++i)
|
||||
{
|
||||
if (s[i-1] == v[0] && s[i] == v[1])
|
||||
continue;
|
||||
|
||||
if (r < result.size())
|
||||
result.set(r++, s[i]);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
Reference in New Issue
Block a user