From 84f6d1f0d6fad3617d7f1b94e3d9bb2852429ea5 Mon Sep 17 00:00:00 2001 From: Daniel Kolesa Date: Thu, 15 Apr 2021 20:26:49 +0200 Subject: [PATCH] make std::span user replaceable this will allow usage on some older compilers for those who want it --- include/cubescript/cubescript/state.hh | 8 ++++---- include/cubescript/cubescript/util.hh | 2 +- include/cubescript/cubescript_conf.hh | 19 +++++++++++++++++++ src/cs_ident.cc | 4 ++-- src/cs_ident.hh | 2 +- src/cs_state.cc | 12 ++++++------ src/cs_val.cc | 2 +- src/cs_vm.cc | 23 +++++++++++++---------- src/lib_list.cc | 6 +++--- src/lib_math.cc | 4 ++-- src/lib_str.cc | 2 +- 11 files changed, 53 insertions(+), 31 deletions(-) diff --git a/include/cubescript/cubescript/state.hh b/include/cubescript/cubescript/state.hh index f43a388..5059627 100644 --- a/include/cubescript/cubescript/state.hh +++ b/include/cubescript/cubescript/state.hh @@ -28,7 +28,7 @@ using alloc_func = void *(*)(void *, void *, size_t, size_t); using hook_func = internal::callable; using command_func = internal::callable< - void, state &, std::span, any_value & + void, state &, span_type, any_value & >; enum class loop_state { @@ -93,13 +93,13 @@ struct LIBCUBESCRIPT_EXPORT state { alias *get_alias(std::string_view name); bool have_ident(std::string_view name); - std::span get_idents(); - std::span get_idents() const; + span_type get_idents(); + span_type get_idents() const; any_value run(bcode_ref const &code); any_value run(std::string_view code); any_value run(std::string_view code, std::string_view source); - any_value run(ident &id, std::span args); + any_value run(ident &id, span_type args); loop_state run_loop(bcode_ref const &code, any_value &ret); loop_state run_loop(bcode_ref const &code); diff --git a/include/cubescript/cubescript/util.hh b/include/cubescript/cubescript/util.hh index d9b1065..c59d175 100644 --- a/include/cubescript/cubescript/util.hh +++ b/include/cubescript/cubescript/util.hh @@ -98,7 +98,7 @@ LIBCUBESCRIPT_EXPORT char const *parse_word( ); LIBCUBESCRIPT_EXPORT string_ref concat_values( - state &cs, std::span vals, + state &cs, span_type vals, std::string_view sep = std::string_view{} ); diff --git a/include/cubescript/cubescript_conf.hh b/include/cubescript/cubescript_conf.hh index 6a9d831..5358a04 100644 --- a/include/cubescript/cubescript_conf.hh +++ b/include/cubescript/cubescript_conf.hh @@ -18,6 +18,12 @@ #include +#if __has_include() +# include +#else +# error "This implementation does not provide an std::span." +#endif + namespace cubescript { /** @brief The integer type used. * @@ -45,6 +51,19 @@ namespace cubescript { */ using float_type = float; +#if __has_include() || 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 + using span_type = std::span; +#else + using span_type = void; +#endif + /** @brief The integer format used. * * This is a formatting specifier as in `printf`, corresponding to the diff --git a/src/cs_ident.cc b/src/cs_ident.cc index 8d051a5..dc14bab 100644 --- a/src/cs_ident.cc +++ b/src/cs_ident.cc @@ -89,7 +89,7 @@ void var_changed(thread_state &ts, ident *id) { auto *cimp = static_cast(cid); any_value val{}; val.set_ident(id); - cimp->call(ts, std::span{&val, 1}, val); + cimp->call(ts, span_type{&val, 1}, val); } void ivar_impl::save_val() { @@ -105,7 +105,7 @@ void svar_impl::save_val() { } void command_impl::call( - thread_state &ts, std::span args, any_value &ret + thread_state &ts, span_type args, any_value &ret ) { auto idstsz = ts.idstack.size(); try { diff --git a/src/cs_ident.hh b/src/cs_ident.hh index 0d6fd5d..d8a676c 100644 --- a/src/cs_ident.hh +++ b/src/cs_ident.hh @@ -126,7 +126,7 @@ struct command_impl: ident_impl, command { string_ref name, string_ref args, int numargs, command_func func ); - void call(thread_state &ts, std::span args, any_value &ret); + void call(thread_state &ts, span_type args, any_value &ret); string_ref p_cargs; command_func p_cb_cftv; diff --git a/src/cs_state.cc b/src/cs_state.cc index f1ce8bb..01cf8ef 100644 --- a/src/cs_state.cc +++ b/src/cs_state.cc @@ -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(); } -LIBCUBESCRIPT_EXPORT std::span state::get_idents() { - return std::span{ +LIBCUBESCRIPT_EXPORT span_type state::get_idents() { + return span_type{ p_tstate->istate->identmap.data(), p_tstate->istate->identmap.size() }; } -LIBCUBESCRIPT_EXPORT std::span state::get_idents() const { +LIBCUBESCRIPT_EXPORT span_type state::get_idents() const { auto ptr = const_cast(p_tstate->istate->identmap.data()); - return std::span{ptr, p_tstate->istate->identmap.size()}; + return span_type{ptr, p_tstate->istate->identmap.size()}; } 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::FVAR: case ident_type::SVAR: - run(*id, std::span{&v, 1}); + run(*id, span_type{&v, 1}); break; default: throw error{ @@ -666,7 +666,7 @@ LIBCUBESCRIPT_EXPORT any_value state::run( } LIBCUBESCRIPT_EXPORT any_value state::run( - ident &id, std::span args + ident &id, span_type args ) { any_value ret{}; std::size_t nargs = args.size(); diff --git a/src/cs_val.cc b/src/cs_val.cc index 899590f..447e5f0 100644 --- a/src/cs_val.cc +++ b/src/cs_val.cc @@ -385,7 +385,7 @@ bool any_value::get_bool() const { /* public utilities */ LIBCUBESCRIPT_EXPORT string_ref concat_values( - state &cs, std::span vals, std::string_view sep + state &cs, span_type vals, std::string_view sep ) { charbuf buf{cs}; for (std::size_t i = 0; i < vals.size(); ++i) { diff --git a/src/cs_vm.cc b/src/cs_vm.cc index 7e94ddf..b2a9574 100644 --- a/src/cs_vm.cc +++ b/src/cs_vm.cc @@ -172,17 +172,17 @@ void exec_command( i = std::max(i + 1, numargs); any_value tv{}; tv.set_string(concat_values( - *ts.pstate, std::span{args, std::size_t(i)}, " " + *ts.pstate, span_type{args, std::size_t(i)}, " " )); static_cast(id)->call( - ts, std::span(&tv, &tv + 1), res + ts, span_type(&tv, &tv + 1), res ); return; } case 'V': i = std::max(i + 1, numargs); static_cast(id)->call( - ts, std::span{args, std::size_t(i)}, res + ts, span_type{args, std::size_t(i)}, res ); return; case '1': @@ -198,7 +198,7 @@ void exec_command( } ++i; static_cast(id)->call( - ts, std::span{args, std::size_t(i)}, res + ts, span_type{args, std::size_t(i)}, res ); res.force_plain(); } @@ -936,8 +936,9 @@ std::uint32_t *vm_exec( case BC_INST_CONC_W | BC_RET_INT: { std::size_t numconc = op >> 8; auto buf = concat_values( - cs, std::span{&args[args.size() - numconc], numconc}, - ((op & BC_INST_OP_MASK) == BC_INST_CONC) ? " " : "" + cs, span_type{ + &args[args.size() - numconc], numconc + }, ((op & BC_INST_OP_MASK) == BC_INST_CONC) ? " " : "" ); args.resize(args.size() - numconc); args.emplace_back().set_string(buf); @@ -1202,7 +1203,7 @@ noid: ); std::size_t offset = args.size() - id->get_num_args(); result.force_none(); - id->call(ts, std::span{ + id->call(ts, span_type{ &args[offset], std::size_t(id->get_num_args()) }, result); force_arg(cs, result, op & BC_INST_RET_MASK); @@ -1220,7 +1221,9 @@ noid: std::size_t callargs = *code++; std::size_t offset = args.size() - callargs; result.force_none(); - id->call(ts, std::span{&args[offset], callargs}, result); + id->call( + ts, span_type{&args[offset], callargs}, result + ); force_arg(cs, result, op & BC_INST_RET_MASK); args.resize(offset); continue; @@ -1237,10 +1240,10 @@ noid: result.force_none(); { any_value tv{}; - tv.set_string(concat_values(cs, std::span{ + tv.set_string(concat_values(cs, span_type{ &args[offset], callargs }, " ")); - id->call(ts, std::span{&tv, 1}, result); + id->call(ts, span_type{&tv, 1}, result); } force_arg(cs, result, op & BC_INST_RET_MASK); args.resize(offset); diff --git a/src/lib_list.cc b/src/lib_list.cc index e9c1574..7448531 100644 --- a/src/lib_list.cc +++ b/src/lib_list.cc @@ -34,7 +34,7 @@ struct arg_val { template static inline void list_find( - state &cs, std::span args, any_value &res, F cmp + state &cs, span_type args, any_value &res, F cmp ) { integer_type n = 0, skip = args[2].get_integer(); T val = arg_val::get(args[1], cs); @@ -56,7 +56,7 @@ notfound: template static inline void list_assoc( - state &cs, std::span args, any_value &res, F cmp + state &cs, span_type args, any_value &res, F cmp ) { T val = arg_val::get(args[1], cs); for (list_parser p{cs, args[0].get_string(cs)}; p.parse();) { @@ -117,7 +117,7 @@ int list_includes( template static inline void list_merge( - state &cs, std::span args, any_value &res, F cmp + state &cs, span_type args, any_value &res, F cmp ) { std::string_view list = args[0].get_string(cs); std::string_view elems = args[1].get_string(cs); diff --git a/src/lib_math.cc b/src/lib_math.cc index 040ab59..fb5a6a0 100644 --- a/src/lib_math.cc +++ b/src/lib_math.cc @@ -46,7 +46,7 @@ struct math_noop { template static inline void math_op( - std::span args, any_value &res, T initval, + span_type args, any_value &res, T initval, F1 binop, F2 unop ) { T val; @@ -62,7 +62,7 @@ static inline void math_op( } template -static inline void cmp_op(std::span args, any_value &res, F cmp) { +static inline void cmp_op(span_type args, any_value &res, F cmp) { bool val; if (args.size() >= 2) { val = cmp(math_val::get(args[0]), math_val::get(args[1])); diff --git a/src/lib_str.cc b/src/lib_str.cc index 4cd6185..1fc349e 100644 --- a/src/lib_str.cc +++ b/src/lib_str.cc @@ -11,7 +11,7 @@ namespace cubescript { template static inline void str_cmp_by( - state &cs, std::span args, any_value &res, F cfunc + state &cs, span_type args, any_value &res, F cfunc ) { bool val; if (args.size() >= 2) {