ChaiScript/include/chaiscript/chaiscript_stdlib.hpp
leftibot b7315f2db9 Fix #458: Support std::string_view interop with ChaiScript strings
Register std::string_view as the "string_view" user type with a built-in
implicit conversion from std::string, so a ChaiScript string can be passed
directly to a C++ function taking std::string_view. Adds the reverse
explicit conversion via string(sv) / to_string(sv), plus basic queries
(size, length, empty, data) and comparison operators on string_view.
String-style methods that take size_t (substr, find, ...) are intentionally
not duplicated on string_view: with the implicit conversion in place they
would create dispatch ambiguity for calls like string.substr(int, int).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 20:48:30 -06:00

84 lines
2.8 KiB
C++

// This file is distributed under the BSD License.
// See "license.txt" for details.
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
// and Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com
#ifndef CHAISCRIPT_STDLIB_HPP_
#define CHAISCRIPT_STDLIB_HPP_
#include <map>
#include <memory>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
#include "chaiscript_defines.hpp"
#include "language/chaiscript_common.hpp"
#include "dispatchkit/function_call.hpp"
// #include "dispatchkit/dispatchkit.hpp"
#include "dispatchkit/bootstrap.hpp"
#include "dispatchkit/bootstrap_stl.hpp"
#include "dispatchkit/operators.hpp"
// #include "dispatchkit/boxed_value.hpp"
#include "dispatchkit/register_function.hpp"
#include "language/chaiscript_prelude.hpp"
#include "utility/json_wrap.hpp"
#ifndef CHAISCRIPT_NO_THREADS
#include <future>
#endif
/// @file
///
/// This file generates the standard library that normal ChaiScript usage requires.
namespace chaiscript {
class Std_Lib {
public:
[[nodiscard]] static ModulePtr library(const std::vector<Library_Options> &t_opts = {}) {
if (std::find(t_opts.begin(), t_opts.end(), Library_Options::No_Stdlib) != t_opts.end()) {
return std::make_shared<Module>();
}
auto lib = std::make_shared<Module>();
const bool no_prelude = std::find(t_opts.begin(), t_opts.end(), Library_Options::No_Prelude) != t_opts.end();
const bool no_json = std::find(t_opts.begin(), t_opts.end(), Library_Options::No_JSON) != t_opts.end();
bootstrap::Bootstrap::bootstrap(*lib);
bootstrap::standard_library::vector_type<std::vector<Boxed_Value>>("Vector", *lib);
bootstrap::standard_library::string_type<std::string>("string", *lib);
bootstrap::standard_library::string_view_type<std::string_view, std::string>("string_view", *lib);
bootstrap::standard_library::map_type<std::map<std::string, Boxed_Value>>("Map", *lib);
bootstrap::standard_library::pair_type<std::pair<Boxed_Value, Boxed_Value>>("Pair", *lib);
// Allow explicit conversion from std::string_view back to std::string,
// e.g. `string(sv)` in ChaiScript.
lib->add(fun([](const std::string_view sv) { return std::string{sv}; }), "string");
#ifndef CHAISCRIPT_NO_THREADS
bootstrap::standard_library::future_type<std::future<chaiscript::Boxed_Value>>("future", *lib);
// Note: async() is registered in ChaiScript_Basic::build_eval_system()
// with thread tracking to prevent heap-use-after-free on engine destruction.
#endif
if (!no_json) {
json_wrap::library(*lib);
}
if (!no_prelude) {
lib->eval(ChaiScript_Prelude::chaiscript_prelude() /*, "standard prelude"*/);
}
return lib;
}
};
} // namespace chaiscript
#endif