make std::span user replaceable

this will allow usage on some older compilers for those who want it
master
Daniel Kolesa 2021-04-15 20:26:49 +02:00
parent 8b1aaa63fe
commit 84f6d1f0d6
11 changed files with 53 additions and 31 deletions

View File

@ -28,7 +28,7 @@ using alloc_func = void *(*)(void *, void *, size_t, size_t);
using hook_func = internal::callable<void, state &>; using hook_func = internal::callable<void, state &>;
using command_func = internal::callable< using command_func = internal::callable<
void, state &, std::span<any_value>, any_value & void, state &, span_type<any_value>, any_value &
>; >;
enum class loop_state { enum class loop_state {
@ -93,13 +93,13 @@ struct LIBCUBESCRIPT_EXPORT state {
alias *get_alias(std::string_view name); alias *get_alias(std::string_view name);
bool have_ident(std::string_view name); bool have_ident(std::string_view name);
std::span<ident *> get_idents(); span_type<ident *> get_idents();
std::span<ident const *> get_idents() const; span_type<ident const *> get_idents() const;
any_value run(bcode_ref const &code); any_value run(bcode_ref const &code);
any_value run(std::string_view code); any_value run(std::string_view code);
any_value run(std::string_view code, std::string_view source); any_value run(std::string_view code, std::string_view source);
any_value run(ident &id, std::span<any_value> args); any_value run(ident &id, span_type<any_value> args);
loop_state run_loop(bcode_ref const &code, any_value &ret); loop_state run_loop(bcode_ref const &code, any_value &ret);
loop_state run_loop(bcode_ref const &code); loop_state run_loop(bcode_ref const &code);

View File

@ -98,7 +98,7 @@ LIBCUBESCRIPT_EXPORT char const *parse_word(
); );
LIBCUBESCRIPT_EXPORT string_ref concat_values( LIBCUBESCRIPT_EXPORT string_ref concat_values(
state &cs, std::span<any_value> vals, state &cs, span_type<any_value> vals,
std::string_view sep = std::string_view{} std::string_view sep = std::string_view{}
); );

View File

@ -18,6 +18,12 @@
#include <type_traits> #include <type_traits>
#if __has_include(<span>)
# include <span>
#else
# error "This implementation does not provide an std::span<T>."
#endif
namespace cubescript { namespace cubescript {
/** @brief The integer type used. /** @brief The integer type used.
* *
@ -45,6 +51,19 @@ namespace cubescript {
*/ */
using float_type = float; using float_type = float;
#if __has_include(<span>) || defined(LIBCS_GENERATING_DOC)
/** @brief The span type used.
*
* By default, this is `std::span`. You will almost never want to override
* this, but an alternative implementation can be supplied if your standard
* library does not support it.
*/
template<typename T>
using span_type = std::span<T>;
#else
using span_type = void;
#endif
/** @brief The integer format used. /** @brief The integer format used.
* *
* This is a formatting specifier as in `printf`, corresponding to the * This is a formatting specifier as in `printf`, corresponding to the

View File

@ -89,7 +89,7 @@ void var_changed(thread_state &ts, ident *id) {
auto *cimp = static_cast<command_impl *>(cid); auto *cimp = static_cast<command_impl *>(cid);
any_value val{}; any_value val{};
val.set_ident(id); val.set_ident(id);
cimp->call(ts, std::span<any_value>{&val, 1}, val); cimp->call(ts, span_type<any_value>{&val, 1}, val);
} }
void ivar_impl::save_val() { void ivar_impl::save_val() {
@ -105,7 +105,7 @@ void svar_impl::save_val() {
} }
void command_impl::call( void command_impl::call(
thread_state &ts, std::span<any_value> args, any_value &ret thread_state &ts, span_type<any_value> args, any_value &ret
) { ) {
auto idstsz = ts.idstack.size(); auto idstsz = ts.idstack.size();
try { try {

View File

@ -126,7 +126,7 @@ struct command_impl: ident_impl, command {
string_ref name, string_ref args, int numargs, command_func func string_ref name, string_ref args, int numargs, command_func func
); );
void call(thread_state &ts, std::span<any_value> args, any_value &ret); void call(thread_state &ts, span_type<any_value> args, any_value &ret);
string_ref p_cargs; string_ref p_cargs;
command_func p_cb_cftv; command_func p_cb_cftv;

View File

@ -331,16 +331,16 @@ LIBCUBESCRIPT_EXPORT bool state::have_ident(std::string_view name) {
return p_tstate->istate->idents.find(name) != p_tstate->istate->idents.end(); return p_tstate->istate->idents.find(name) != p_tstate->istate->idents.end();
} }
LIBCUBESCRIPT_EXPORT std::span<ident *> state::get_idents() { LIBCUBESCRIPT_EXPORT span_type<ident *> state::get_idents() {
return std::span<ident *>{ return span_type<ident *>{
p_tstate->istate->identmap.data(), p_tstate->istate->identmap.data(),
p_tstate->istate->identmap.size() p_tstate->istate->identmap.size()
}; };
} }
LIBCUBESCRIPT_EXPORT std::span<ident const *> state::get_idents() const { LIBCUBESCRIPT_EXPORT span_type<ident const *> state::get_idents() const {
auto ptr = const_cast<ident const **>(p_tstate->istate->identmap.data()); auto ptr = const_cast<ident const **>(p_tstate->istate->identmap.data());
return std::span<ident const *>{ptr, p_tstate->istate->identmap.size()}; return span_type<ident const *>{ptr, p_tstate->istate->identmap.size()};
} }
LIBCUBESCRIPT_EXPORT void state::clear_override(ident &id) { LIBCUBESCRIPT_EXPORT void state::clear_override(ident &id) {
@ -510,7 +510,7 @@ LIBCUBESCRIPT_EXPORT void state::set_alias(
case ident_type::IVAR: case ident_type::IVAR:
case ident_type::FVAR: case ident_type::FVAR:
case ident_type::SVAR: case ident_type::SVAR:
run(*id, std::span<any_value>{&v, 1}); run(*id, span_type<any_value>{&v, 1});
break; break;
default: default:
throw error{ throw error{
@ -666,7 +666,7 @@ LIBCUBESCRIPT_EXPORT any_value state::run(
} }
LIBCUBESCRIPT_EXPORT any_value state::run( LIBCUBESCRIPT_EXPORT any_value state::run(
ident &id, std::span<any_value> args ident &id, span_type<any_value> args
) { ) {
any_value ret{}; any_value ret{};
std::size_t nargs = args.size(); std::size_t nargs = args.size();

View File

@ -385,7 +385,7 @@ bool any_value::get_bool() const {
/* public utilities */ /* public utilities */
LIBCUBESCRIPT_EXPORT string_ref concat_values( LIBCUBESCRIPT_EXPORT string_ref concat_values(
state &cs, std::span<any_value> vals, std::string_view sep state &cs, span_type<any_value> vals, std::string_view sep
) { ) {
charbuf buf{cs}; charbuf buf{cs};
for (std::size_t i = 0; i < vals.size(); ++i) { for (std::size_t i = 0; i < vals.size(); ++i) {

View File

@ -172,17 +172,17 @@ void exec_command(
i = std::max(i + 1, numargs); i = std::max(i + 1, numargs);
any_value tv{}; any_value tv{};
tv.set_string(concat_values( tv.set_string(concat_values(
*ts.pstate, std::span{args, std::size_t(i)}, " " *ts.pstate, span_type<any_value>{args, std::size_t(i)}, " "
)); ));
static_cast<command_impl *>(id)->call( static_cast<command_impl *>(id)->call(
ts, std::span<any_value>(&tv, &tv + 1), res ts, span_type<any_value>(&tv, &tv + 1), res
); );
return; return;
} }
case 'V': case 'V':
i = std::max(i + 1, numargs); i = std::max(i + 1, numargs);
static_cast<command_impl *>(id)->call( static_cast<command_impl *>(id)->call(
ts, std::span{args, std::size_t(i)}, res ts, span_type<any_value>{args, std::size_t(i)}, res
); );
return; return;
case '1': case '1':
@ -198,7 +198,7 @@ void exec_command(
} }
++i; ++i;
static_cast<command_impl *>(id)->call( static_cast<command_impl *>(id)->call(
ts, std::span<any_value>{args, std::size_t(i)}, res ts, span_type<any_value>{args, std::size_t(i)}, res
); );
res.force_plain(); res.force_plain();
} }
@ -936,8 +936,9 @@ std::uint32_t *vm_exec(
case BC_INST_CONC_W | BC_RET_INT: { case BC_INST_CONC_W | BC_RET_INT: {
std::size_t numconc = op >> 8; std::size_t numconc = op >> 8;
auto buf = concat_values( auto buf = concat_values(
cs, std::span{&args[args.size() - numconc], numconc}, cs, span_type<any_value>{
((op & BC_INST_OP_MASK) == BC_INST_CONC) ? " " : "" &args[args.size() - numconc], numconc
}, ((op & BC_INST_OP_MASK) == BC_INST_CONC) ? " " : ""
); );
args.resize(args.size() - numconc); args.resize(args.size() - numconc);
args.emplace_back().set_string(buf); args.emplace_back().set_string(buf);
@ -1202,7 +1203,7 @@ noid:
); );
std::size_t offset = args.size() - id->get_num_args(); std::size_t offset = args.size() - id->get_num_args();
result.force_none(); result.force_none();
id->call(ts, std::span<any_value>{ id->call(ts, span_type<any_value>{
&args[offset], std::size_t(id->get_num_args()) &args[offset], std::size_t(id->get_num_args())
}, result); }, result);
force_arg(cs, result, op & BC_INST_RET_MASK); force_arg(cs, result, op & BC_INST_RET_MASK);
@ -1220,7 +1221,9 @@ noid:
std::size_t callargs = *code++; std::size_t callargs = *code++;
std::size_t offset = args.size() - callargs; std::size_t offset = args.size() - callargs;
result.force_none(); result.force_none();
id->call(ts, std::span{&args[offset], callargs}, result); id->call(
ts, span_type<any_value>{&args[offset], callargs}, result
);
force_arg(cs, result, op & BC_INST_RET_MASK); force_arg(cs, result, op & BC_INST_RET_MASK);
args.resize(offset); args.resize(offset);
continue; continue;
@ -1237,10 +1240,10 @@ noid:
result.force_none(); result.force_none();
{ {
any_value tv{}; any_value tv{};
tv.set_string(concat_values(cs, std::span{ tv.set_string(concat_values(cs, span_type<any_value>{
&args[offset], callargs &args[offset], callargs
}, " ")); }, " "));
id->call(ts, std::span<any_value>{&tv, 1}, result); id->call(ts, span_type<any_value>{&tv, 1}, result);
} }
force_arg(cs, result, op & BC_INST_RET_MASK); force_arg(cs, result, op & BC_INST_RET_MASK);
args.resize(offset); args.resize(offset);

View File

@ -34,7 +34,7 @@ struct arg_val<std::string_view> {
template<typename T, typename F> template<typename T, typename F>
static inline void list_find( static inline void list_find(
state &cs, std::span<any_value> args, any_value &res, F cmp state &cs, span_type<any_value> args, any_value &res, F cmp
) { ) {
integer_type n = 0, skip = args[2].get_integer(); integer_type n = 0, skip = args[2].get_integer();
T val = arg_val<T>::get(args[1], cs); T val = arg_val<T>::get(args[1], cs);
@ -56,7 +56,7 @@ notfound:
template<typename T, typename F> template<typename T, typename F>
static inline void list_assoc( static inline void list_assoc(
state &cs, std::span<any_value> args, any_value &res, F cmp state &cs, span_type<any_value> args, any_value &res, F cmp
) { ) {
T val = arg_val<T>::get(args[1], cs); T val = arg_val<T>::get(args[1], cs);
for (list_parser p{cs, args[0].get_string(cs)}; p.parse();) { for (list_parser p{cs, args[0].get_string(cs)}; p.parse();) {
@ -117,7 +117,7 @@ int list_includes(
template<bool PushList, bool Swap, typename F> template<bool PushList, bool Swap, typename F>
static inline void list_merge( static inline void list_merge(
state &cs, std::span<any_value> args, any_value &res, F cmp state &cs, span_type<any_value> args, any_value &res, F cmp
) { ) {
std::string_view list = args[0].get_string(cs); std::string_view list = args[0].get_string(cs);
std::string_view elems = args[1].get_string(cs); std::string_view elems = args[1].get_string(cs);

View File

@ -46,7 +46,7 @@ struct math_noop {
template<typename T, typename F1, typename F2> template<typename T, typename F1, typename F2>
static inline void math_op( static inline void math_op(
std::span<any_value> args, any_value &res, T initval, span_type<any_value> args, any_value &res, T initval,
F1 binop, F2 unop F1 binop, F2 unop
) { ) {
T val; T val;
@ -62,7 +62,7 @@ static inline void math_op(
} }
template<typename T, typename F> template<typename T, typename F>
static inline void cmp_op(std::span<any_value> args, any_value &res, F cmp) { static inline void cmp_op(span_type<any_value> args, any_value &res, F cmp) {
bool val; bool val;
if (args.size() >= 2) { if (args.size() >= 2) {
val = cmp(math_val<T>::get(args[0]), math_val<T>::get(args[1])); val = cmp(math_val<T>::get(args[0]), math_val<T>::get(args[1]));

View File

@ -11,7 +11,7 @@ namespace cubescript {
template<typename F> template<typename F>
static inline void str_cmp_by( static inline void str_cmp_by(
state &cs, std::span<any_value> args, any_value &res, F cfunc state &cs, span_type<any_value> args, any_value &res, F cfunc
) { ) {
bool val; bool val;
if (args.size() >= 2) { if (args.size() >= 2) {