Merge caed2c2948d1042bc2f0d71c78411b8da1557860 into f635b51e3f8e95868210edfc66fdbd8e475710f5

This commit is contained in:
Rob Loach 2026-06-14 01:17:27 -04:00 committed by GitHub
commit 75de5e6d10
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 130 additions and 15 deletions

View File

@ -580,8 +580,37 @@ namespace chaiscript::bootstrap::standard_library {
m.add(fun([](const StringView *s, const StringView &f, size_t pos) { return s->find_last_not_of(f, pos); }), "find_last_not_of");
m.add(fun([](const StringView *s, const StringView &f, size_t pos) { return s->find_first_not_of(f, pos); }), "find_first_not_of");
m.add(fun([](const StringView *s, const StringView &f) { return s->starts_with(f); }), "starts_with");
m.add(fun([](const StringView *s, const StringView &f) { return s->ends_with(f); }), "ends_with");
#if __cplusplus >= 202002L
m.add(fun([](const StringView *s, const StringView &f) { return s->starts_with(f); }), "starts_with");
m.add(fun([](const StringView *s, const StringView &f) { return s->ends_with(f); }), "ends_with");
#else
m.add(fun([](const StringView *s, const StringView &f) -> bool {
using size_type = typename StringView::size_type;
const size_type fsz = f.size();
if (fsz == 0) {
return true;
}
if (fsz > s->size()) {
return false;
}
return s->compare(size_type{0}, fsz, f) == 0;
}),
"starts_with");
m.add(fun([](const StringView *s, const StringView &f) -> bool {
using size_type = typename StringView::size_type;
const size_type fsz = f.size();
if (fsz == 0) {
return true;
}
const size_type ssz = s->size();
if (fsz > ssz) {
return false;
}
return s->compare(ssz - fsz, fsz, f) == 0;
}),
"ends_with");
#endif
m.add(fun([](const StringView *s, size_t pos, size_t len) { return s->substr(pos, len); }), "substr");

View File

@ -12,6 +12,9 @@
#include "boxed_value.hpp"
// std::span was introduced in >= C++20, so we implement a small
// wrapper around it if it's not available.
#if __cplusplus >= 202002L
#include <span>
namespace chaiscript {
@ -20,4 +23,70 @@ namespace chaiscript {
} // namespace chaiscript
#else
namespace chaiscript {
class Function_Params {
public:
constexpr Function_Params(const Boxed_Value *const t_begin, const Boxed_Value *const t_end)
: m_begin(t_begin)
, m_end(t_end) {
}
explicit Function_Params(const Boxed_Value &bv)
: m_begin(&bv)
, m_end(m_begin + 1) {
}
explicit Function_Params(const std::vector<Boxed_Value> &vec)
: m_begin(vec.empty() ? nullptr : vec.data())
, m_end(vec.empty() ? nullptr : vec.data() + vec.size()) {
}
template<size_t Size>
constexpr explicit Function_Params(const std::array<Boxed_Value, Size> &a)
: m_begin(a.data())
, m_end(a.data() + Size) {
}
[[nodiscard]] constexpr const Boxed_Value &operator[](const std::size_t t_i) const noexcept { return m_begin[t_i]; }
[[nodiscard]] constexpr const Boxed_Value *begin() const noexcept { return m_begin; }
[[nodiscard]] constexpr const Boxed_Value &front() const noexcept { return *m_begin; }
[[nodiscard]] constexpr const Boxed_Value &first() const noexcept { return *m_begin; }
[[nodiscard]] constexpr Function_Params first(std::size_t t_count) const noexcept { return Function_Params(m_begin, m_begin + t_count); }
[[nodiscard]] constexpr Function_Params subspan(std::size_t t_offset, std::size_t t_count = std::size_t(-1)) const noexcept {
const auto *begin = m_begin + t_offset;
const auto *end = (t_count == std::size_t(-1)) ? m_end : begin + t_count;
return Function_Params(begin, end);
}
[[nodiscard]] constexpr const Boxed_Value *end() const noexcept { return m_end; }
[[nodiscard]] constexpr std::size_t size() const noexcept { return static_cast<std::size_t>(m_end - m_begin); }
[[nodiscard]] std::vector<Boxed_Value> to_vector() const { return std::vector<Boxed_Value>{m_begin, m_end}; }
[[nodiscard]] constexpr bool empty() const noexcept { return m_begin == m_end; }
private:
const Boxed_Value *m_begin = nullptr;
const Boxed_Value *m_end = nullptr;
};
// Constructor specialization for array of size 0
template<>
constexpr Function_Params::Function_Params(const std::array<Boxed_Value, size_t{0}> & /* a */)
: m_begin(nullptr)
, m_end(nullptr) {
}
} // namespace chaiscript
#endif
#endif

View File

@ -12,6 +12,19 @@
#include <type_traits>
/**
* std::type_identity was introduced in >= C++20 so we put
* together a small shim for it if it doesn't exist.
*/
#if !defined(__cpp_lib_type_identity)
namespace std {
template<typename T>
struct type_identity { using type = T; };
template<typename T>
using type_identity_t = typename type_identity<T>::type;
}
#endif
#include "bind_first.hpp"
#include "function_signature.hpp"
#include "proxy_functions.hpp"

View File

@ -1246,7 +1246,7 @@ namespace chaiscript {
const auto &ns_name = this->children[0]->text;
auto ns_name_bv = const_var(ns_name);
t_ss->call_function("namespace", m_ns_loc, Function_Params{&ns_name_bv, 1}, t_ss.conversions());
t_ss->call_function("namespace", m_ns_loc, Function_Params{&ns_name_bv, &ns_name_bv + 1}, t_ss.conversions());
std::vector<std::string> parts;
{
@ -1350,7 +1350,7 @@ namespace chaiscript {
};
const auto call_function = [&t_ss](const auto &t_funcs, const Boxed_Value &t_param) {
return dispatch::dispatch(*t_funcs, Function_Params{&t_param, 1}, t_ss.conversions());
return dispatch::dispatch(*t_funcs, Function_Params{&t_param, &t_param + 1}, t_ss.conversions());
};
const std::string &loop_var_name = this->children[0]->text;
@ -1646,8 +1646,8 @@ namespace chaiscript {
return Boxed_Number::do_oper(m_oper, bv);
} else {
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
fpp.save_params(Function_Params{&bv, 1});
return t_ss->call_function(this->text, m_loc, Function_Params{&bv, 1}, t_ss.conversions());
fpp.save_params(Function_Params{&bv, &bv + 1});
return t_ss->call_function(this->text, m_loc, Function_Params{&bv, &bv + 1}, t_ss.conversions());
}
} catch (const exception::dispatch_error &e) {
throw exception::eval_error("Error with prefix operator evaluation: '" + this->text + "'", e.parameters, e.functions, false, *t_ss);
@ -1755,7 +1755,7 @@ namespace chaiscript {
if (dispatch::Param_Types(
std::vector<std::pair<std::string, Type_Info>>{Arg_List_AST_Node<T>::get_arg_type(*catch_block.children[0], t_ss)})
.match(Function_Params{&t_except, 1}, t_ss.conversions())
.match(Function_Params{&t_except, &t_except + 1}, t_ss.conversions())
.first) {
t_ss.add_object(name, t_except);

View File

@ -1029,7 +1029,7 @@ namespace chaiscript {
template<typename string_type>
struct Char_Parser {
string_type &match;
using char_type = string_type::value_type;
using char_type = typename string_type::value_type;
bool is_escaped = false;
bool is_interpolated = false;
bool saw_interpolation_marker = false;
@ -2941,7 +2941,11 @@ namespace chaiscript {
/// Parses the given input string, tagging parsed ast_nodes with the given m_filename.
AST_NodePtr parse_internal(const std::string &t_input, std::string t_fname) {
const auto begin = t_input.empty() ? nullptr : &t_input.front();
#if __cplusplus >= 202002L
const auto end = begin == nullptr ? nullptr : std::next(begin, std::ssize(t_input));
#else
const auto end = begin == nullptr ? nullptr : std::next(begin, (int)std::size(t_input));
#endif
m_position = Position(begin, end);
m_filename = std::make_shared<std::string>(std::move(t_fname));

View File

@ -128,10 +128,10 @@ namespace chaiscript::json {
}
JSONWrapper(std::nullptr_t) {}
Container::iterator begin() { return object ? object->begin() : typename Container::iterator(); }
Container::iterator end() { return object ? object->end() : typename Container::iterator(); }
[[nodiscard]] Container::const_iterator begin() const { return object ? object->begin() : typename Container::iterator(); }
[[nodiscard]] Container::const_iterator end() const { return object ? object->end() : typename Container::iterator(); }
typename Container::iterator begin() { return object ? object->begin() : typename Container::iterator(); }
typename Container::iterator end() { return object ? object->end() : typename Container::iterator(); }
[[nodiscard]] typename Container::const_iterator begin() const { return object ? object->begin() : typename Container::const_iterator(); }
[[nodiscard]] typename Container::const_iterator end() const { return object ? object->end() : typename Container::const_iterator(); }
};
template<typename Container>
@ -144,10 +144,10 @@ namespace chaiscript::json {
}
JSONConstWrapper(std::nullptr_t) {}
[[nodiscard]] Container::const_iterator begin() const noexcept {
[[nodiscard]] typename Container::const_iterator begin() const noexcept {
return object ? object->begin() : typename Container::const_iterator();
}
[[nodiscard]] Container::const_iterator end() const noexcept { return object ? object->end() : typename Container::const_iterator(); }
[[nodiscard]] typename Container::const_iterator end() const noexcept { return object ? object->end() : typename Container::const_iterator(); }
};
JSON() = default;

View File

@ -33,7 +33,7 @@ namespace chaiscript::utility {
return std::string_view(data, m_size) == other;
}
constexpr bool operator==(const std::string &t_str) const noexcept { return std::equal(begin(), end(), std::cbegin(t_str), std::cend(t_str)); }
constexpr bool operator==(const std::string &t_str) const noexcept { return std::string_view(data, m_size) == std::string_view(t_str); }
const size_t m_size;
const char *data = nullptr;