Merge pull request #556 from BerndAmend/develop

Fixes for #527, #537, #553, C++20, and various compiler warnings/errors reported by g++ 11.1, clang 11, and vs2019
This commit is contained in:
Rob Loach 2021-05-23 17:23:11 -04:00 committed by GitHub
commit 6491b80496
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 7121 additions and 2215 deletions

View File

@ -1,12 +1,12 @@
cmake_minimum_required(VERSION 2.8) cmake_minimum_required(VERSION 3.12)
cmake_policy(SET CMP0054 NEW)
if(NOT ${CMAKE_VERSION} VERSION_LESS "3.1")
cmake_policy(SET CMP0054 NEW)
endif()
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
# required since cmake 3.4 at least for libc++
set(CMAKE_ENABLE_EXPORTS ON)
project(chaiscript) project(chaiscript)
option(MULTITHREAD_SUPPORT_ENABLED "Multithreaded Support Enabled" TRUE) option(MULTITHREAD_SUPPORT_ENABLED "Multithreaded Support Enabled" TRUE)
@ -62,27 +62,26 @@ if(CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
endif() endif()
option(ENABLE_LTO "Enable Link Time Optimization" FALSE) option(ENABLE_LTO "Enable Link Time Optimization" FALSE)
if(ENABLE_LTO)
if (ENABLE_LTO) check_ipo_supported()
add_definitions(-flto) set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
set(LINKER_FLAGS "${LINKER_FLAGS} -flto")
endif() endif()
option(GPROF_OUTPUT "Generate profile data" FALSE) option(GPROF_OUTPUT "Generate profile data" FALSE)
if (GPROF_OUTPUT) if(GPROF_OUTPUT)
add_definitions(-pg) add_definitions(-pg)
set(LINKER_FLAGS "${LINKER_FLAGS} -pg") set(LINKER_FLAGS "${LINKER_FLAGS} -pg")
endif() endif()
option(PROFILE_GENERATE "Generate profile data" FALSE) option(PROFILE_GENERATE "Generate profile data" FALSE)
if (PROFILE_GENERATE) if(PROFILE_GENERATE)
add_definitions(-fprofile-generate) add_definitions(-fprofile-generate)
set(LINKER_FLAGS "${LINKER_FLAGS} -fprofile-generate") set(LINKER_FLAGS "${LINKER_FLAGS} -fprofile-generate")
endif() endif()
option(PROFILE_USE "Use profile data" FALSE) option(PROFILE_USE "Use profile data" FALSE)
if (PROFILE_USE) if(PROFILE_USE)
add_definitions(-fprofile-use) add_definitions(-fprofile-use)
set(LINKER_FLAGS "${LINKER_FLAGS} -fprofile-use") set(LINKER_FLAGS "${LINKER_FLAGS} -fprofile-use")
endif() endif()
@ -127,7 +126,7 @@ if(NOT MINGW)
find_library(READLINE_LIBRARY NAMES readline PATH /usr/lib /usr/local/lib /opt/local/lib) find_library(READLINE_LIBRARY NAMES readline PATH /usr/lib /usr/local/lib /opt/local/lib)
endif() endif()
if (UNIX AND NOT APPLE) if(UNIX AND NOT APPLE)
find_program(VALGRIND NAMES valgrind PATH /usr/bin /usr/local/bin) find_program(VALGRIND NAMES valgrind PATH /usr/bin /usr/local/bin)
endif() endif()
@ -145,19 +144,10 @@ else()
set(READLINE_FLAG) set(READLINE_FLAG)
endif() endif()
if(CMAKE_COMPILER_IS_GNUCC)
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
set(CPP17_FLAG "-std=c++1z")
endif()
if(MSVC) if(MSVC)
add_definitions(/std:c++latest /W4 /w14545 /w34242 /w34254 /w34287 /w44263 /w44265 /w44296 /w44311 /w44826 /we4289 /w14546 /w14547 /w14549 /w14555 /w14619 /w14905 /w14906 /w14928) add_definitions(/W4 /w14545 /w34242 /w34254 /w34287 /w44263 /w44265 /w44296 /w44311 /w44826 /we4289 /w14546 /w14547 /w14549 /w14555 /w14619 /w14905 /w14906 /w14928)
add_definitions(/std:c++17) if(MSVC_VERSION STREQUAL "1800")
if (MSVC_VERSION STREQUAL "1800")
# VS2013 doesn't have magic statics # VS2013 doesn't have magic statics
add_definitions(/w44640) add_definitions(/w44640)
else() else()
@ -165,7 +155,7 @@ if(MSVC)
add_definitions(/w34062) add_definitions(/w34062)
endif() endif()
add_definitions(/bigobj /permissive-) add_definitions(/bigobj /permissive- /utf-8)
# Note on MSVC compiler flags. # Note on MSVC compiler flags.
# The code base selective disables warnings as necessary when the compiler is complaining too much # The code base selective disables warnings as necessary when the compiler is complaining too much
# about something that is perfectly valid, or there is simply no technical way around it # about something that is perfectly valid, or there is simply no technical way around it
@ -175,10 +165,10 @@ if(MSVC)
# how to workaround or fix the error. So I'm disabling it globally. # how to workaround or fix the error. So I'm disabling it globally.
add_definitions(/wd4503) add_definitions(/wd4503)
else() else()
add_definitions(-Wall -Wextra -Wconversion -Wshadow -Wnon-virtual-dtor -Wold-style-cast -Wcast-align -Wcast-qual -Wunused -Woverloaded-virtual -Wno-noexcept-type -Wpedantic ${CPP17_FLAG}) add_definitions(-Wall -Wextra -Wconversion -Wshadow -Wnon-virtual-dtor -Wold-style-cast -Wcast-align -Wcast-qual -Wunused -Woverloaded-virtual -Wno-noexcept-type -Wpedantic -Werror=return-type)
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
add_definitions(-Weverything -Wno-c++98-compat-pedantic -Wno-c++98-compat -Wno-documentation -Wno-switch-enum -Wno-weak-vtables -Wno-missing-prototypes -Wno-padded -Wno-missing-noreturn -Wno-exit-time-destructors -Wno-documentation-unknown-command -Wno-unused-template -Wno-undef ) add_definitions(-Weverything -Wno-c++98-compat-pedantic -Wno-c++98-compat -Wno-documentation -Wno-switch-enum -Wno-weak-vtables -Wno-missing-prototypes -Wno-padded -Wno-missing-noreturn -Wno-exit-time-destructors -Wno-documentation-unknown-command -Wno-unused-template -Wno-undef -Wno-double-promotion)
else() else()
add_definitions(-Wnoexcept) add_definitions(-Wnoexcept)
endif() endif()
@ -189,16 +179,12 @@ else()
endif() endif()
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
option(USE_LIBCXX "Use clang's libcxx" TRUE) option(USE_LIBCXX "Use clang's libcxx" FALSE)
if(USE_LIBCXX) if(USE_LIBCXX)
add_definitions(-stdlib=libc++) add_definitions(-stdlib=libc++)
set(LINKER_FLAGS "${LINKER_FLAGS} ${CPP17_FLAG} -stdlib=libc++") set(LINKER_FLAGS "${LINKER_FLAGS} -stdlib=libc++")
else()
set(LINKER_FLAGS "${LINKER_FLAGS} ${CPP17_FLAG}")
endif() endif()
elseif(CMAKE_COMPILER_IS_GNUCC)
set(LINKER_FLAGS "${LINKER_FLAGS} ${CPP17_FLAG}")
endif() endif()
# limitations in MinGW require us to make an optimized build # limitations in MinGW require us to make an optimized build
@ -297,7 +283,7 @@ file(GLOB PERFORMANCE_TESTS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/performance_tes
list(SORT PERFORMANCE_TESTS) list(SORT PERFORMANCE_TESTS)
if (RUN_FUZZY_TESTS) if(RUN_FUZZY_TESTS)
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/unittests") file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/unittests")
@ -357,7 +343,7 @@ if(BUILD_TESTING)
list(APPEND TESTS unit.${filename}) list(APPEND TESTS unit.${filename})
endforeach() endforeach()
if (RUN_PERFORMANCE_TESTS) if(RUN_PERFORMANCE_TESTS)
foreach(filename ${PERFORMANCE_TESTS}) foreach(filename ${PERFORMANCE_TESTS})
message(STATUS "Adding performance test ${filename}") message(STATUS "Adding performance test ${filename}")
@ -414,10 +400,8 @@ if(BUILD_TESTING)
"CHAI_USE_PATH=${CMAKE_CURRENT_SOURCE_DIR}/unittests/" "CHAI_USE_PATH=${CMAKE_CURRENT_SOURCE_DIR}/unittests/"
"CHAI_MODULE_PATH=${CMAKE_CURRENT_BINARY_DIR}/" "CHAI_MODULE_PATH=${CMAKE_CURRENT_BINARY_DIR}/"
) )
endif() endif()
add_executable(multifile_test add_executable(multifile_test
unittests/multifile_test_main.cpp unittests/multifile_test_main.cpp
unittests/multifile_test_chai.cpp unittests/multifile_test_chai.cpp
@ -431,7 +415,6 @@ if(BUILD_TESTING)
endif() endif()
if(BUILD_LIBFUZZ_TESTER) if(BUILD_LIBFUZZ_TESTER)
add_executable(fuzzer src/libfuzzer_client.cpp src/sha3.cpp) add_executable(fuzzer src/libfuzzer_client.cpp src/sha3.cpp)
target_compile_options(fuzzer PRIVATE "-fsanitize=fuzzer,address") target_compile_options(fuzzer PRIVATE "-fsanitize=fuzzer,address")

View File

@ -832,11 +832,11 @@ namespace chaiscript
public: public:
ChaiScript(std::vector<std::string> t_modulepaths = {}, ChaiScript(std::vector<std::string> t_modulepaths = {},
std::vector<std::string> t_usepaths = {}, std::vector<std::string> t_usepaths = {},
const std::vector<Options> &t_opts = chaiscript::default_options()) std::vector<Options> t_opts = chaiscript::default_options())
: ChaiScript_Basic( : ChaiScript_Basic(
chaiscript::Std_Lib::library(), chaiscript::Std_Lib::library(),
std::make_unique<parser::ChaiScript_Parser<eval::Noop_Tracer, optimizer::Optimizer_Default>>(), std::make_unique<parser::ChaiScript_Parser<eval::Noop_Tracer, optimizer::Optimizer_Default>>(),
t_modulepaths, t_usepaths, t_opts) std::move(t_modulepaths), std::move(t_usepaths), std::move(t_opts))
{ {
} }
}; };

View File

@ -257,7 +257,7 @@ namespace chaiscript {
}; };
template< class From, class To > template< class From, class To >
inline constexpr bool is_nothrow_forward_constructible_v static inline constexpr bool is_nothrow_forward_constructible_v
= is_nothrow_forward_constructible<From, To>::value; = is_nothrow_forward_constructible<From, To>::value;
template<typename Container, typename ... T> template<typename Container, typename ... T>
@ -281,7 +281,7 @@ namespace chaiscript {
static inline std::vector<Options> default_options() [[nodiscard]] inline std::vector<Options> default_options()
{ {
#ifdef CHAISCRIPT_NO_DYNLOAD #ifdef CHAISCRIPT_NO_DYNLOAD
return {Options::No_Load_Modules, Options::External_Scripts}; return {Options::No_Load_Modules, Options::External_Scripts};

View File

@ -288,10 +288,8 @@ namespace chaiscript
return callable(*static_cast<const float *>(bv.get_const_ptr())); return callable(*static_cast<const float *>(bv.get_const_ptr()));
case Common_Types::t_long_double: case Common_Types::t_long_double:
return callable(*static_cast<const long double *>(bv.get_const_ptr())); return callable(*static_cast<const long double *>(bv.get_const_ptr()));
default:
throw chaiscript::detail::exception::bad_any_cast();
} }
throw chaiscript::detail::exception::bad_any_cast();
} }
inline static Boxed_Value oper(Operators::Opers t_oper, const Boxed_Value &t_lhs) inline static Boxed_Value oper(Operators::Opers t_oper, const Boxed_Value &t_lhs)

View File

@ -81,23 +81,23 @@ namespace chaiscript {
template<typename Ret, typename ... Params> template<typename Ret, typename ... Params>
struct Function_Signature<Ret (Params...)> struct Function_Signature<Ret (Params...)>
{ {
typedef Ret Return_Type; using Return_Type = Ret;
typedef Ret (Signature)(Params...); using Signature = Ret ()(Params...);
}; };
template<typename Ret, typename T, typename ... Params> template<typename Ret, typename T, typename ... Params>
struct Function_Signature<Ret (T::*)(Params...) const> struct Function_Signature<Ret (T::*)(Params...) const>
{ {
typedef Ret Return_Type; using Return_Type = Ret;
typedef Ret (Signature)(Params...); using Signature = Ret ()(Params...);
}; };
template<typename T> template<typename T>
struct Callable_Traits struct Callable_Traits
{ {
typedef typename Function_Signature<decltype(&T::operator())>::Signature Signature; using Signature = typename Function_Signature<decltype(&T::operator())>::Signature;
typedef typename Function_Signature<decltype(&T::operator())>::Return_Type Return_Type; using Return_Type = typename Function_Signature<decltype(&T::operator())>::Return_Type;
}; };
} }
} }

View File

@ -198,7 +198,7 @@ namespace chaiscript
apply_globals(m_globals.begin(), m_globals.end(), t_engine); apply_globals(m_globals.begin(), m_globals.end(), t_engine);
} }
bool has_function(const Proxy_Function &new_f, const std::string_view &name) noexcept bool has_function(const Proxy_Function &new_f, std::string_view name) noexcept
{ {
return std::any_of(m_funcs.begin(), m_funcs.end(), return std::any_of(m_funcs.begin(), m_funcs.end(),
[&](const std::pair<Proxy_Function, std::string> &existing_f) { [&](const std::pair<Proxy_Function, std::string> &existing_f) {
@ -617,7 +617,7 @@ namespace chaiscript
/// Searches the current stack for an object of the given name /// Searches the current stack for an object of the given name
/// includes a special overload for the _ place holder object to /// includes a special overload for the _ place holder object to
/// ensure that it is always in scope. /// ensure that it is always in scope.
Boxed_Value get_object(const std::string_view &name, std::atomic_uint_fast32_t &t_loc, Stack_Holder &t_holder) const Boxed_Value get_object(std::string_view name, std::atomic_uint_fast32_t &t_loc, Stack_Holder &t_holder) const
{ {
enum class Loc : uint_fast32_t { enum class Loc : uint_fast32_t {
located = 0x80000000, located = 0x80000000,
@ -739,7 +739,7 @@ namespace chaiscript
/// Return a function by name /// Return a function by name
std::pair<size_t, std::shared_ptr<std::vector< Proxy_Function>>> get_function(const std::string_view &t_name, const size_t t_hint) const std::pair<size_t, std::shared_ptr<std::vector< Proxy_Function>>> get_function(std::string_view t_name, const size_t t_hint) const
{ {
chaiscript::detail::threading::shared_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex); chaiscript::detail::threading::shared_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
@ -765,7 +765,7 @@ namespace chaiscript
/// \returns a function object (Boxed_Value wrapper) if it exists /// \returns a function object (Boxed_Value wrapper) if it exists
/// \throws std::range_error if it does not /// \throws std::range_error if it does not
/// \warn does not obtain a mutex lock. \sa get_function_object for public version /// \warn does not obtain a mutex lock. \sa get_function_object for public version
std::pair<size_t, Boxed_Value> get_function_object_int(const std::string_view &t_name, const size_t t_hint) const std::pair<size_t, Boxed_Value> get_function_object_int(std::string_view t_name, const size_t t_hint) const
{ {
const auto &funs = get_boxed_functions_int(); const auto &funs = get_boxed_functions_int();
@ -779,7 +779,7 @@ namespace chaiscript
/// Return true if a function exists /// Return true if a function exists
bool function_exists(const std::string_view &name) const bool function_exists(std::string_view name) const
{ {
chaiscript::detail::threading::shared_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex); chaiscript::detail::threading::shared_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
@ -1035,7 +1035,7 @@ namespace chaiscript
Boxed_Value call_function(const std::string_view &t_name, std::atomic_uint_fast32_t &t_loc, const Function_Params &params, Boxed_Value call_function(std::string_view t_name, std::atomic_uint_fast32_t &t_loc, const Function_Params &params,
const Type_Conversions_State &t_conversions) const const Type_Conversions_State &t_conversions) const
{ {
uint_fast32_t loc = t_loc; uint_fast32_t loc = t_loc;
@ -1116,7 +1116,7 @@ namespace chaiscript
} }
/// return true if the Boxed_Value matches the registered type by name /// return true if the Boxed_Value matches the registered type by name
bool is_type(const Boxed_Value &r, const std::string_view &user_typename) const noexcept bool is_type(const Boxed_Value &r, std::string_view user_typename) const noexcept
{ {
try { try {
if (get_type(user_typename).bare_equal(r.get_type_info())) if (get_type(user_typename).bare_equal(r.get_type_info()))
@ -1450,10 +1450,10 @@ namespace chaiscript
} }
void add_object(const std::string &t_name, Boxed_Value obj) const { void add_object(const std::string &t_name, Boxed_Value obj) const {
return m_engine.get().add_object(t_name, std::move(obj), m_stack_holder.get()); m_engine.get().add_object(t_name, std::move(obj), m_stack_holder.get());
} }
Boxed_Value get_object(const std::string_view &t_name, std::atomic_uint_fast32_t &t_loc) const { Boxed_Value get_object(std::string_view t_name, std::atomic_uint_fast32_t &t_loc) const {
return m_engine.get().get_object(t_name, t_loc, m_stack_holder.get()); return m_engine.get().get_object(t_name, t_loc, m_stack_holder.get());
} }

View File

@ -83,7 +83,7 @@ namespace chaiscript
bool is_attribute_function() const noexcept override { return m_is_attribute; } bool is_attribute_function() const noexcept override { return m_is_attribute; }
bool call_match(const Function_Params &vals, const Type_Conversions_State &t_conversions) const noexcept override bool call_match(const chaiscript::Function_Params &vals, const Type_Conversions_State &t_conversions) const noexcept override
{ {
if (dynamic_object_typename_match(vals, m_type_name, m_ti, t_conversions)) if (dynamic_object_typename_match(vals, m_type_name, m_ti, t_conversions))
{ {
@ -99,7 +99,7 @@ namespace chaiscript
} }
protected: protected:
Boxed_Value do_call(const Function_Params &params, const Type_Conversions_State &t_conversions) const override Boxed_Value do_call(const chaiscript::Function_Params &params, const Type_Conversions_State &t_conversions) const override
{ {
if (dynamic_object_typename_match(params, m_type_name, m_ti, t_conversions)) if (dynamic_object_typename_match(params, m_type_name, m_ti, t_conversions))
{ {
@ -148,7 +148,7 @@ namespace chaiscript
} }
bool dynamic_object_typename_match(const Function_Params &bvs, const std::string &name, bool dynamic_object_typename_match(const chaiscript::Function_Params &bvs, const std::string &name,
const std::unique_ptr<Type_Info> &ti, const Type_Conversions_State &t_conversions) const noexcept const std::unique_ptr<Type_Info> &ti, const Type_Conversions_State &t_conversions) const noexcept
{ {
if (!bvs.empty()) if (!bvs.empty())
@ -205,22 +205,22 @@ namespace chaiscript
return (dc != nullptr) && dc->m_type_name == m_type_name && (*dc->m_func) == (*m_func); return (dc != nullptr) && dc->m_type_name == m_type_name && (*dc->m_func) == (*m_func);
} }
bool call_match(const Function_Params &vals, const Type_Conversions_State &t_conversions) const override bool call_match(const chaiscript::Function_Params &vals, const Type_Conversions_State &t_conversions) const override
{ {
std::vector<Boxed_Value> new_vals{Boxed_Value(Dynamic_Object(m_type_name))}; std::vector<Boxed_Value> new_vals{Boxed_Value(Dynamic_Object(m_type_name))};
new_vals.insert(new_vals.end(), vals.begin(), vals.end()); new_vals.insert(new_vals.end(), vals.begin(), vals.end());
return m_func->call_match(Function_Params{new_vals}, t_conversions); return m_func->call_match(chaiscript::Function_Params{new_vals}, t_conversions);
} }
protected: protected:
Boxed_Value do_call(const Function_Params &params, const Type_Conversions_State &t_conversions) const override Boxed_Value do_call(const chaiscript::Function_Params &params, const Type_Conversions_State &t_conversions) const override
{ {
auto bv = Boxed_Value(Dynamic_Object(m_type_name), true); auto bv = Boxed_Value(Dynamic_Object(m_type_name), true);
std::vector<Boxed_Value> new_params{bv}; std::vector<Boxed_Value> new_params{bv};
new_params.insert(new_params.end(), params.begin(), params.end()); new_params.insert(new_params.end(), params.begin(), params.end());
(*m_func)(Function_Params{new_params}, t_conversions); (*m_func)(chaiscript::Function_Params{new_params}, t_conversions);
return bv; return bv;
} }

View File

@ -57,10 +57,10 @@ namespace chaiscript {
} }
[[nodiscard]] constexpr std::size_t size() const noexcept { [[nodiscard]] constexpr std::size_t size() const noexcept {
return m_end - m_begin; return std::size_t(m_end - m_begin);
} }
std::vector<Boxed_Value> to_vector() const { [[nodiscard]] std::vector<Boxed_Value> to_vector() const {
return std::vector<Boxed_Value>{m_begin, m_end}; return std::vector<Boxed_Value>{m_begin, m_end};
} }
@ -71,7 +71,6 @@ namespace chaiscript {
private: private:
const Boxed_Value *m_begin = nullptr; const Boxed_Value *m_begin = nullptr;
const Boxed_Value *m_end = nullptr; const Boxed_Value *m_end = nullptr;
}; };
// Constructor specialization for array of size 0 // Constructor specialization for array of size 0
@ -83,6 +82,4 @@ namespace chaiscript {
} }
#endif #endif

View File

@ -110,7 +110,7 @@ template<typename Ret, typename Class, typename... Param>
Function_Signature(Ret (Class::*f)(Param...) const &&noexcept)->Function_Signature<Ret, Function_Params<const Class &&, Param...>, true, true>; Function_Signature(Ret (Class::*f)(Param...) const &&noexcept)->Function_Signature<Ret, Function_Params<const Class &&, Param...>, true, true>;
template<typename Ret, typename Class> template<typename Ret, typename Class>
Function_Signature(Ret(Class::*f))->Function_Signature<Ret, Function_Params<Class &>, true, true, true>; Function_Signature(Ret Class::*f)->Function_Signature<Ret, Function_Params<Class &>, true, true, true>;
// primary template handles types that have no nested ::type member: // primary template handles types that have no nested ::type member:
template<class, class = std::void_t<>> template<class, class = std::void_t<>>

View File

@ -36,14 +36,14 @@ namespace chaiscript
struct Handle_Return struct Handle_Return
{ {
template<typename T, template<typename T,
typename = std::enable_if_t<std::is_pod_v<std::decay_t<T>>>> typename = typename std::enable_if_t<std::is_trivial_v<typename std::decay_t<T>>>>
static Boxed_Value handle(T r) static Boxed_Value handle(T r)
{ {
return Boxed_Value(std::move(r), true); return Boxed_Value(std::move(r), true);
} }
template<typename T, template<typename T,
typename = std::enable_if_t<!std::is_pod_v<std::decay_t<T>>>> typename = typename std::enable_if_t<!(std::is_trivial_v<typename std::decay_t<T>>)>>
static Boxed_Value handle(T &&r) static Boxed_Value handle(T &&r)
{ {
return Boxed_Value(std::make_shared<T>(std::forward<T>(r)), true); return Boxed_Value(std::make_shared<T>(std::forward<T>(r)), true);

View File

@ -22,12 +22,21 @@ namespace chaiscript
template<typename Class, typename ... Params > template<typename Class, typename ... Params >
Proxy_Function build_constructor_(Class (*)(Params...)) Proxy_Function build_constructor_(Class (*)(Params...))
{ {
auto call = [](auto && ... param){ if constexpr (!std::is_copy_constructible_v<Class>) {
return Class(std::forward<decltype(param)>(param)...); auto call = [](auto && ... param) {
}; return std::make_shared<Class>(std::forward<decltype(param)>(param)...);
};
return Proxy_Function( return Proxy_Function(
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Callable_Impl<Class (Params...), decltype(call)>>(call)); chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Callable_Impl<std::shared_ptr<Class> (Params...), decltype(call)>>(call));
} else if constexpr (true) {
auto call = [](auto && ... param){
return Class(std::forward<decltype(param)>(param)...);
};
return Proxy_Function(
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Callable_Impl<Class (Params...), decltype(call)>>(call));
}
} }
} }
} }

View File

@ -35,7 +35,7 @@ namespace chaiscript
{ {
public: public:
conversion_error(const Type_Info t_to, const Type_Info t_from, const utility::Static_String what) noexcept conversion_error(const Type_Info t_to, const Type_Info t_from, const utility::Static_String what) noexcept
: bad_boxed_cast(t_from, (*t_to.bare_type_info()), what), type_to(t_to) {}; : bad_boxed_cast(t_from, (*t_to.bare_type_info()), what), type_to(t_to) {}
Type_Info type_to; Type_Info type_to;
}; };
@ -355,10 +355,10 @@ namespace chaiscript
} }
Type_Conversions(const Type_Conversions &t_other) = delete; Type_Conversions(const Type_Conversions &t_other) = delete;
Type_Conversions(Type_Conversions &&) = default; Type_Conversions(Type_Conversions &&) = delete;
Type_Conversions &operator=(const Type_Conversions &) = delete; Type_Conversions &operator=(const Type_Conversions &) = delete;
Type_Conversions &operator=(Type_Conversions &&) = default; Type_Conversions &operator=(Type_Conversions &&) = delete;
const std::set<const std::type_info *, Less_Than> &thread_cache() const const std::set<const std::type_info *, Less_Than> &thread_cache() const
{ {

View File

@ -150,8 +150,6 @@ namespace chaiscript
template<typename T> template<typename T>
struct Get_Type_Info<std::shared_ptr<T> > struct Get_Type_Info<std::shared_ptr<T> >
{ {
// typedef T type;
constexpr static Type_Info get() noexcept constexpr static Type_Info get() noexcept
{ {
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value, return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,

View File

@ -50,7 +50,7 @@ namespace chaiscript
return opers[static_cast<int>(t_oper)]; return opers[static_cast<int>(t_oper)];
} }
constexpr static Opers to_operator(const std::string_view &t_str, bool t_is_unary = false) noexcept constexpr static Opers to_operator(std::string_view t_str, bool t_is_unary = false) noexcept
{ {
#ifdef CHAISCRIPT_MSVC #ifdef CHAISCRIPT_MSVC
#pragma warning(push) #pragma warning(push)

View File

@ -581,7 +581,7 @@ namespace chaiscript
virtual ~AST_Node() noexcept = default; virtual ~AST_Node() noexcept = default;
AST_Node(AST_Node &&) = default; AST_Node(AST_Node &&) = default;
AST_Node &operator=(AST_Node &&) = default; AST_Node &operator=(AST_Node &&) = delete;
AST_Node(const AST_Node &) = delete; AST_Node(const AST_Node &) = delete;
AST_Node& operator=(const AST_Node &) = delete; AST_Node& operator=(const AST_Node &) = delete;
@ -693,7 +693,7 @@ namespace chaiscript
struct Scope_Push_Pop struct Scope_Push_Pop
{ {
Scope_Push_Pop(Scope_Push_Pop &&) = default; Scope_Push_Pop(Scope_Push_Pop &&) = default;
Scope_Push_Pop& operator=(Scope_Push_Pop &&) = default; Scope_Push_Pop& operator=(Scope_Push_Pop &&) = delete;
Scope_Push_Pop(const Scope_Push_Pop &) = delete; Scope_Push_Pop(const Scope_Push_Pop &) = delete;
Scope_Push_Pop& operator=(const Scope_Push_Pop &) = delete; Scope_Push_Pop& operator=(const Scope_Push_Pop &) = delete;
@ -717,7 +717,7 @@ namespace chaiscript
struct Function_Push_Pop struct Function_Push_Pop
{ {
Function_Push_Pop(Function_Push_Pop &&) = default; Function_Push_Pop(Function_Push_Pop &&) = default;
Function_Push_Pop& operator=(Function_Push_Pop &&) = default; Function_Push_Pop& operator=(Function_Push_Pop &&) = delete;
Function_Push_Pop(const Function_Push_Pop &) = delete; Function_Push_Pop(const Function_Push_Pop &) = delete;
Function_Push_Pop& operator=(const Function_Push_Pop &) = delete; Function_Push_Pop& operator=(const Function_Push_Pop &) = delete;
@ -746,7 +746,7 @@ namespace chaiscript
struct Stack_Push_Pop struct Stack_Push_Pop
{ {
Stack_Push_Pop(Stack_Push_Pop &&) = default; Stack_Push_Pop(Stack_Push_Pop &&) = default;
Stack_Push_Pop& operator=(Stack_Push_Pop &&) = default; Stack_Push_Pop& operator=(Stack_Push_Pop &&) = delete;
Stack_Push_Pop(const Stack_Push_Pop &) = delete; Stack_Push_Pop(const Stack_Push_Pop &) = delete;
Stack_Push_Pop& operator=(const Stack_Push_Pop &) = delete; Stack_Push_Pop& operator=(const Stack_Push_Pop &) = delete;

View File

@ -60,7 +60,7 @@ namespace chaiscript
namespace detail namespace detail
{ {
typedef std::shared_ptr<Loadable_Module> Loadable_Module_Ptr; using Loadable_Module_Ptr = std::shared_ptr<Loadable_Module>;
} }
@ -178,7 +178,7 @@ namespace chaiscript
if (std::find(t_opts.begin(), t_opts.end(), Options::No_Load_Modules) == t_opts.end() if (std::find(t_opts.begin(), t_opts.end(), Options::No_Load_Modules) == t_opts.end()
&& std::find(t_opts.begin(), t_opts.end(), Options::Load_Modules) != t_opts.end()) && std::find(t_opts.begin(), t_opts.end(), Options::Load_Modules) != t_opts.end())
{ {
m_engine.add(fun([this](const std::string &t_module, const std::string &t_file){ return load_module(t_module, t_file); }), "load_module"); m_engine.add(fun([this](const std::string &t_module, const std::string &t_file){ load_module(t_module, t_file); }), "load_module");
m_engine.add(fun([this](const std::string &t_module){ return load_module(t_module); }), "load_module"); m_engine.add(fun([this](const std::string &t_module){ return load_module(t_module); }), "load_module");
} }
@ -201,7 +201,7 @@ namespace chaiscript
m_engine.add(fun([this](const Boxed_Value &t_bv, const std::string &t_name){ set_global(t_bv, t_name); }), "set_global"); m_engine.add(fun([this](const Boxed_Value &t_bv, const std::string &t_name){ set_global(t_bv, t_name); }), "set_global");
// why this unused parameter to Namespace? // why this unused parameter to Namespace?
m_engine.add(fun([this](const std::string& t_namespace_name) { register_namespace([](Namespace& /*space*/) {}, t_namespace_name); import(t_namespace_name); }), "namespace"); m_engine.add(fun([this](const std::string& t_namespace_name) { register_namespace([] (Namespace& /*space*/) noexcept {}, t_namespace_name); import(t_namespace_name); }), "namespace");
m_engine.add(fun([this](const std::string& t_namespace_name) { import(t_namespace_name); }), "import"); m_engine.add(fun([this](const std::string& t_namespace_name) { import(t_namespace_name); }), "import");
} }

View File

@ -51,12 +51,12 @@ namespace chaiscript
{ {
/// Helper function that will set up the scope around a function call, including handling the named function parameters /// Helper function that will set up the scope around a function call, including handling the named function parameters
template<typename T> template<typename T>
static Boxed_Value eval_function(chaiscript::detail::Dispatch_Engine &t_ss, const AST_Node_Impl<T> &t_node, const std::vector<std::string> &t_param_names, const Function_Params &t_vals, const std::map<std::string, Boxed_Value> *t_locals=nullptr, bool has_this_capture = false) { Boxed_Value eval_function(chaiscript::detail::Dispatch_Engine &t_ss, const AST_Node_Impl<T> &t_node, const std::vector<std::string> &t_param_names, const Function_Params &t_vals, const std::map<std::string, Boxed_Value> *t_locals=nullptr, bool has_this_capture = false) {
chaiscript::detail::Dispatch_State state(t_ss); chaiscript::detail::Dispatch_State state(t_ss);
const Boxed_Value *thisobj = [&]() -> const Boxed_Value *{ const Boxed_Value *thisobj = [&]() -> const Boxed_Value *{
if (auto &stack = t_ss.get_stack_data(state.stack_holder()).back(); if (auto &stack = t_ss.get_stack_data(state.stack_holder()).back();
!stack.empty() && stack.back().first == "__this") !stack.empty() && stack.back().first == "__this")
{ {
return &stack.back().second; return &stack.back().second;
} else if (!t_vals.empty()) { } else if (!t_vals.empty()) {
@ -85,7 +85,7 @@ namespace chaiscript
return t_node.eval(state); return t_node.eval(state);
} catch (detail::Return_Value &rv) { } catch (detail::Return_Value &rv) {
return std::move(rv.retval); return std::move(rv.retval);
} }
} }
inline Boxed_Value clone_if_necessary(Boxed_Value incoming, std::atomic_uint_fast32_t &t_loc, const chaiscript::detail::Dispatch_State &t_ss) inline Boxed_Value clone_if_necessary(Boxed_Value incoming, std::atomic_uint_fast32_t &t_loc, const chaiscript::detail::Dispatch_State &t_ss)
@ -110,9 +110,9 @@ namespace chaiscript
} }
template<typename T> template<typename T>
struct AST_Node_Impl : AST_Node struct AST_Node_Impl : AST_Node
{ {
AST_Node_Impl(std::string t_ast_node_text, AST_Node_Type t_id, Parse_Location t_loc, AST_Node_Impl(std::string t_ast_node_text, AST_Node_Type t_id, Parse_Location t_loc,
std::vector<AST_Node_Impl_Ptr<T>> t_children = std::vector<AST_Node_Impl_Ptr<T>>()) std::vector<AST_Node_Impl_Ptr<T>> t_children = std::vector<AST_Node_Impl_Ptr<T>>())
: AST_Node(std::move(t_ast_node_text), t_id, std::move(t_loc)), : AST_Node(std::move(t_ast_node_text), t_id, std::move(t_loc)),
children(std::move(t_children)) children(std::move(t_children))
@ -187,7 +187,7 @@ namespace chaiscript
} }
protected: protected:
Boxed_Value do_oper(const chaiscript::detail::Dispatch_State &t_ss, Boxed_Value do_oper(const chaiscript::detail::Dispatch_State &t_ss,
const std::string &t_oper_string, const Boxed_Value &t_lhs) const const std::string &t_oper_string, const Boxed_Value &t_lhs) const
{ {
try { try {
@ -234,7 +234,7 @@ namespace chaiscript
} }
protected: protected:
Boxed_Value do_oper(const chaiscript::detail::Dispatch_State &t_ss, Boxed_Value do_oper(const chaiscript::detail::Dispatch_State &t_ss,
Operators::Opers t_oper, const std::string &t_oper_string, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) const Operators::Opers t_oper, const std::string &t_oper_string, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) const
{ {
try { try {
@ -309,7 +309,7 @@ namespace chaiscript
template<typename T> template<typename T>
struct Fun_Call_AST_Node : AST_Node_Impl<T> { struct Fun_Call_AST_Node : AST_Node_Impl<T> {
Fun_Call_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_Node_Impl_Ptr<T>> t_children) : Fun_Call_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_Node_Impl_Ptr<T>> t_children) :
AST_Node_Impl<T>(std::move(t_ast_node_text), AST_Node_Type::Fun_Call, std::move(t_loc), std::move(t_children)) { AST_Node_Impl<T>(std::move(t_ast_node_text), AST_Node_Type::Fun_Call, std::move(t_loc), std::move(t_children)) {
assert(!this->children.empty()); assert(!this->children.empty());
} }
@ -416,7 +416,7 @@ namespace chaiscript
return retval; return retval;
} }
static std::pair<std::string, Type_Info> get_arg_type(const AST_Node_Impl<T> &t_node, const chaiscript::detail::Dispatch_State &t_ss) static std::pair<std::string, Type_Info> get_arg_type(const AST_Node_Impl<T> &t_node, const chaiscript::detail::Dispatch_State &t_ss)
{ {
if (t_node.children.size() < 2) if (t_node.children.size() < 2)
{ {
@ -441,7 +441,7 @@ namespace chaiscript
template<typename T> template<typename T>
struct Equation_AST_Node final : AST_Node_Impl<T> { struct Equation_AST_Node final : AST_Node_Impl<T> {
Equation_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_Node_Impl_Ptr<T>> t_children) : Equation_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_Node_Impl_Ptr<T>> t_children) :
AST_Node_Impl<T>(std::move(t_ast_node_text), AST_Node_Type::Equation, std::move(t_loc), std::move(t_children)), AST_Node_Impl<T>(std::move(t_ast_node_text), AST_Node_Type::Equation, std::move(t_loc), std::move(t_children)),
m_oper(Operators::to_operator(this->text)) m_oper(Operators::to_operator(this->text))
{ assert(this->children.size() == 2); } { assert(this->children.size() == 2); }
@ -681,10 +681,10 @@ namespace chaiscript
template<typename T> template<typename T>
struct Lambda_AST_Node final : AST_Node_Impl<T> { struct Lambda_AST_Node final : AST_Node_Impl<T> {
Lambda_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_Node_Impl_Ptr<T>> t_children) : Lambda_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_Node_Impl_Ptr<T>> t_children) :
AST_Node_Impl<T>(t_ast_node_text, AST_Node_Impl<T>(t_ast_node_text,
AST_Node_Type::Lambda, AST_Node_Type::Lambda,
std::move(t_loc), std::move(t_loc),
std::vector<AST_Node_Impl_Ptr<T>>(std::make_move_iterator(t_children.begin()), std::vector<AST_Node_Impl_Ptr<T>>(std::make_move_iterator(t_children.begin()),
std::make_move_iterator(std::prev(t_children.end()))) std::make_move_iterator(std::prev(t_children.end())))
), ),
m_param_names(Arg_List_AST_Node<T>::get_arg_names(*this->children[1])), m_param_names(Arg_List_AST_Node<T>::get_arg_names(*this->children[1])),
@ -709,7 +709,7 @@ namespace chaiscript
return Boxed_Value( return Boxed_Value(
dispatch::make_dynamic_proxy_function( dispatch::make_dynamic_proxy_function(
[engine, lambda_node = this->m_lambda_node, param_names = this->m_param_names, captures, [engine, lambda_node = this->m_lambda_node, param_names = this->m_param_names, captures,
this_capture = this->m_this_capture] (const Function_Params &t_params) this_capture = this->m_this_capture] (const Function_Params &t_params)
{ {
return detail::eval_function(engine, *lambda_node, param_names, t_params, &captures, this_capture); return detail::eval_function(engine, *lambda_node, param_names, t_params, &captures, this_capture);
@ -719,8 +719,8 @@ namespace chaiscript
); );
} }
static bool has_this_capture(const std::vector<AST_Node_Impl_Ptr<T>> &children) noexcept { static bool has_this_capture(const std::vector<AST_Node_Impl_Ptr<T>> &t_children) noexcept {
return std::any_of(std::begin(children), std::end(children), return std::any_of(std::begin(t_children), std::end(t_children),
[](const auto &child){ [](const auto &child){
return child->children[0]->text == "this"; return child->children[0]->text == "this";
} }
@ -770,8 +770,8 @@ namespace chaiscript
std::shared_ptr<AST_Node_Impl<T>> m_guard_node; std::shared_ptr<AST_Node_Impl<T>> m_guard_node;
Def_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_Node_Impl_Ptr<T>> t_children) : Def_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_Node_Impl_Ptr<T>> t_children) :
AST_Node_Impl<T>(std::move(t_ast_node_text), AST_Node_Type::Def, std::move(t_loc), AST_Node_Impl<T>(std::move(t_ast_node_text), AST_Node_Type::Def, std::move(t_loc),
std::vector<AST_Node_Impl_Ptr<T>>(std::make_move_iterator(t_children.begin()), std::vector<AST_Node_Impl_Ptr<T>>(std::make_move_iterator(t_children.begin()),
std::make_move_iterator(std::prev(t_children.end(), has_guard(t_children, 1)?2:1))) std::make_move_iterator(std::prev(t_children.end(), has_guard(t_children, 1)?2:1)))
), ),
// This apparent use after move is safe because we are only moving out the specific elements we need // This apparent use after move is safe because we are only moving out the specific elements we need
@ -864,11 +864,11 @@ namespace chaiscript
try { try {
this->children[1]->eval(t_ss); this->children[1]->eval(t_ss);
} catch (detail::Continue_Loop &) { } catch (detail::Continue_Loop &) {
// we got a continue exception, which means all of the remaining // we got a continue exception, which means all of the remaining
// loop implementation is skipped and we just need to continue to // loop implementation is skipped and we just need to continue to
// the next condition test // the next condition test
} }
} }
} catch (detail::Break_Loop &) { } catch (detail::Break_Loop &) {
// loop was broken intentionally // loop was broken intentionally
} }
@ -899,8 +899,8 @@ namespace chaiscript
template<typename T> template<typename T>
struct If_AST_Node final : AST_Node_Impl<T> { struct If_AST_Node final : AST_Node_Impl<T> {
If_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_Node_Impl_Ptr<T>> t_children) : If_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_Node_Impl_Ptr<T>> t_children) :
AST_Node_Impl<T>(std::move(t_ast_node_text), AST_Node_Type::If, std::move(t_loc), std::move(t_children)) AST_Node_Impl<T>(std::move(t_ast_node_text), AST_Node_Type::If, std::move(t_loc), std::move(t_children))
{ {
assert(this->children.size() == 3); assert(this->children.size() == 3);
} }
@ -1000,7 +1000,7 @@ namespace chaiscript
template<typename T> template<typename T>
struct For_AST_Node final : AST_Node_Impl<T> { struct For_AST_Node final : AST_Node_Impl<T> {
For_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_Node_Impl_Ptr<T>> t_children) : For_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_Node_Impl_Ptr<T>> t_children) :
AST_Node_Impl<T>(std::move(t_ast_node_text), AST_Node_Type::For, std::move(t_loc), std::move(t_children)) AST_Node_Impl<T>(std::move(t_ast_node_text), AST_Node_Type::For, std::move(t_loc), std::move(t_children))
{ assert(this->children.size() == 4); } { assert(this->children.size() == 4); }
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{ Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{
@ -1016,7 +1016,7 @@ namespace chaiscript
// Body of Loop // Body of Loop
this->children[3]->eval(t_ss); this->children[3]->eval(t_ss);
} catch (detail::Continue_Loop &) { } catch (detail::Continue_Loop &) {
// we got a continue exception, which means all of the remaining // we got a continue exception, which means all of the remaining
// loop implementation is skipped and we just need to continue to // loop implementation is skipped and we just need to continue to
// the next iteration step // the next iteration step
} }
@ -1078,7 +1078,7 @@ namespace chaiscript
template<typename T> template<typename T>
struct Case_AST_Node final : AST_Node_Impl<T> { struct Case_AST_Node final : AST_Node_Impl<T> {
Case_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_Node_Impl_Ptr<T>> t_children) : Case_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_Node_Impl_Ptr<T>> t_children) :
AST_Node_Impl<T>(std::move(t_ast_node_text), AST_Node_Type::Case, std::move(t_loc), std::move(t_children)) AST_Node_Impl<T>(std::move(t_ast_node_text), AST_Node_Type::Case, std::move(t_loc), std::move(t_children))
{ assert(this->children.size() == 2); /* how many children does it have? */ } { assert(this->children.size() == 2); /* how many children does it have? */ }
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override { Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
@ -1089,7 +1089,7 @@ namespace chaiscript
return void_var(); return void_var();
} }
}; };
template<typename T> template<typename T>
struct Default_AST_Node final : AST_Node_Impl<T> { struct Default_AST_Node final : AST_Node_Impl<T> {
Default_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_Node_Impl_Ptr<T>> t_children) : Default_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_Node_Impl_Ptr<T>> t_children) :
@ -1142,7 +1142,7 @@ namespace chaiscript
std::map<std::string, Boxed_Value> retval; std::map<std::string, Boxed_Value> retval;
for (const auto &child : this->children[0]->children) { for (const auto &child : this->children[0]->children) {
retval.insert(std::make_pair(t_ss->boxed_cast<std::string>(child->children[0]->eval(t_ss)), retval.insert(std::make_pair(t_ss->boxed_cast<std::string>(child->children[0]->eval(t_ss)),
detail::clone_if_necessary(child->children[1]->eval(t_ss), m_loc, t_ss))); detail::clone_if_necessary(child->children[1]->eval(t_ss), m_loc, t_ss)));
} }
@ -1440,7 +1440,7 @@ namespace chaiscript
std::vector<std::string> t_param_names{"this"}; std::vector<std::string> t_param_names{"this"};
dispatch::Param_Types param_types; dispatch::Param_Types param_types;
if ((this->children.size() > 2) if ((this->children.size() > 2)
&& (this->children[2]->identifier == AST_Node_Type::Arg_List)) { && (this->children[2]->identifier == AST_Node_Type::Arg_List)) {
auto args = Arg_List_AST_Node<T>::get_arg_names(*this->children[2]); auto args = Arg_List_AST_Node<T>::get_arg_names(*this->children[2]);
t_param_names.insert(t_param_names.end(), args.begin(), args.end()); t_param_names.insert(t_param_names.end(), args.begin(), args.end());
@ -1455,7 +1455,7 @@ namespace chaiscript
guard = dispatch::make_dynamic_proxy_function( guard = dispatch::make_dynamic_proxy_function(
[engine, t_param_names, guardnode = m_guard_node](const Function_Params &t_params) { [engine, t_param_names, guardnode = m_guard_node](const Function_Params &t_params) {
return chaiscript::eval::detail::eval_function(engine, *guardnode, t_param_names, t_params); return chaiscript::eval::detail::eval_function(engine, *guardnode, t_param_names, t_params);
}, },
static_cast<int>(numparams), m_guard_node); static_cast<int>(numparams), m_guard_node);
} }
@ -1488,7 +1488,7 @@ namespace chaiscript
[engine, t_param_names, node = m_body_node](const Function_Params &t_params) { [engine, t_param_names, node = m_body_node](const Function_Params &t_params) {
return chaiscript::eval::detail::eval_function(engine, *node, t_param_names, t_params); return chaiscript::eval::detail::eval_function(engine, *node, t_param_names, t_params);
}, },
static_cast<int>(numparams), m_body_node, param_types, guard), type), static_cast<int>(numparams), m_body_node, param_types, guard), type),
function_name); function_name);
} }
} catch (const exception::name_conflict_error &e) { } catch (const exception::name_conflict_error &e) {
@ -1504,7 +1504,7 @@ namespace chaiscript
Attr_Decl_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_Node_Impl_Ptr<T>> t_children) : Attr_Decl_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_Node_Impl_Ptr<T>> t_children) :
AST_Node_Impl<T>(std::move(t_ast_node_text), AST_Node_Type::Attr_Decl, std::move(t_loc), std::move(t_children)) { } AST_Node_Impl<T>(std::move(t_ast_node_text), AST_Node_Type::Attr_Decl, std::move(t_loc), std::move(t_children)) { }
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override
{ {
std::string class_name = this->children[0]->text; std::string class_name = this->children[0]->text;
@ -1532,7 +1532,7 @@ namespace chaiscript
template<typename T> template<typename T>
struct Logical_And_AST_Node final : AST_Node_Impl<T> { struct Logical_And_AST_Node final : AST_Node_Impl<T> {
Logical_And_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_Node_Impl_Ptr<T>> t_children) : Logical_And_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_Node_Impl_Ptr<T>> t_children) :
AST_Node_Impl<T>(std::move(t_ast_node_text), AST_Node_Type::Logical_And, std::move(t_loc), std::move(t_children)) AST_Node_Impl<T>(std::move(t_ast_node_text), AST_Node_Type::Logical_And, std::move(t_loc), std::move(t_children))
{ assert(this->children.size() == 2); } { assert(this->children.size() == 2); }
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override
@ -1546,7 +1546,7 @@ namespace chaiscript
template<typename T> template<typename T>
struct Logical_Or_AST_Node final : AST_Node_Impl<T> { struct Logical_Or_AST_Node final : AST_Node_Impl<T> {
Logical_Or_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_Node_Impl_Ptr<T>> t_children) : Logical_Or_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_Node_Impl_Ptr<T>> t_children) :
AST_Node_Impl<T>(std::move(t_ast_node_text), AST_Node_Type::Logical_Or, std::move(t_loc), std::move(t_children)) AST_Node_Impl<T>(std::move(t_ast_node_text), AST_Node_Type::Logical_Or, std::move(t_loc), std::move(t_children))
{ assert(this->children.size() == 2); } { assert(this->children.size() == 2); }
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override

View File

@ -461,8 +461,8 @@ namespace chaiscript {
} }
}; };
typedef Optimizer<optimizer::Partial_Fold, optimizer::Unused_Return, optimizer::Constant_Fold, using Optimizer_Default = Optimizer<optimizer::Partial_Fold, optimizer::Unused_Return, optimizer::Constant_Fold,
optimizer::If, optimizer::Return, optimizer::Dead_Code, optimizer::Block, optimizer::For_Loop, optimizer::Assign_Decl> Optimizer_Default; optimizer::If, optimizer::Return, optimizer::Dead_Code, optimizer::Block, optimizer::For_Loop, optimizer::Assign_Decl>;
} }
} }

View File

@ -232,7 +232,7 @@ namespace chaiscript
std::array<utility::Static_String, 3> m_10 {{SS("*"), SS("/"), SS("%")}}; std::array<utility::Static_String, 3> m_10 {{SS("*"), SS("/"), SS("%")}};
std::array<utility::Static_String, 6> m_11 {{SS("++"), SS("--"), SS("-"), SS("+"), SS("!"), SS("~")}}; std::array<utility::Static_String, 6> m_11 {{SS("++"), SS("--"), SS("-"), SS("+"), SS("!"), SS("~")}};
bool is_match(const std::string_view &t_str) const noexcept { bool is_match(std::string_view t_str) const noexcept {
constexpr std::array<std::size_t, 12> groups{{0,1,2,3,4,5,6,7,8,9,10,11}}; constexpr std::array<std::size_t, 12> groups{{0,1,2,3,4,5,6,7,8,9,10,11}};
return std::any_of(groups.begin(), groups.end(), [&t_str, this](const std::size_t group){ return is_match(group, t_str); }); return std::any_of(groups.begin(), groups.end(), [&t_str, this](const std::size_t group){ return is_match(group, t_str); });
} }
@ -261,7 +261,7 @@ namespace chaiscript
} }
} }
constexpr bool is_match(const std::size_t t_group, const std::string_view &t_str) const noexcept { constexpr bool is_match(const std::size_t t_group, std::string_view t_str) const noexcept {
auto match = [&t_str](const auto &array) { auto match = [&t_str](const auto &array) {
return std::any_of(array.begin(), array.end(), [&t_str](const auto &v){ return v == t_str; }); return std::any_of(array.begin(), array.end(), [&t_str](const auto &v){ return v == t_str; });
}; };
@ -325,7 +325,7 @@ namespace chaiscript
static std::string_view str(const Position &t_begin, const Position &t_end) noexcept { static std::string_view str(const Position &t_begin, const Position &t_end) noexcept {
if (t_begin.m_pos != nullptr && t_end.m_pos != nullptr) { if (t_begin.m_pos != nullptr && t_end.m_pos != nullptr) {
return std::string_view(t_begin.m_pos, std::distance(t_begin.m_pos, t_end.m_pos)); return std::string_view(t_begin.m_pos, std::size_t(std::distance(t_begin.m_pos, t_end.m_pos)));
} else { } else {
return {}; return {};
} }
@ -421,7 +421,7 @@ namespace chaiscript
Tracer m_tracer; Tracer m_tracer;
Optimizer m_optimizer; Optimizer m_optimizer;
void validate_object_name(const std::string_view &name) const void validate_object_name(std::string_view name) const
{ {
if (!Name_Validator::valid_object_name(name)) { if (!Name_Validator::valid_object_name(name)) {
throw exception::eval_error("Invalid Object Name: " + std::string(name), File_Position(m_position.line, m_position.col), *m_filename); throw exception::eval_error("Invalid Object Name: " + std::string(name), File_Position(m_position.line, m_position.col), *m_filename);
@ -724,7 +724,7 @@ namespace chaiscript
} }
/// Parses a floating point value and returns a Boxed_Value representation of it /// Parses a floating point value and returns a Boxed_Value representation of it
static Boxed_Value buildFloat(const std::string_view &t_val) static Boxed_Value buildFloat(std::string_view t_val)
{ {
bool float_ = false; bool float_ = false;
bool long_ = false; bool long_ = false;
@ -784,7 +784,7 @@ namespace chaiscript
} }
} }
if (prefixed) { t_val.remove_prefix(2); }; if (prefixed) { t_val.remove_prefix(2); }
#ifdef __GNUC__ #ifdef __GNUC__
#pragma GCC diagnostic push #pragma GCC diagnostic push
@ -792,6 +792,8 @@ namespace chaiscript
#ifdef CHAISCRIPT_CLANG #ifdef CHAISCRIPT_CLANG
#pragma GCC diagnostic ignored "-Wtautological-compare" #pragma GCC diagnostic ignored "-Wtautological-compare"
#pragma GCC diagnostic ignored "-Wtautological-unsigned-zero-compare"
#pragma GCC diagnostic ignored "-Wtautological-type-limit-compare"
#pragma GCC diagnostic ignored "-Wsign-conversion" #pragma GCC diagnostic ignored "-Wsign-conversion"
#endif #endif
@ -809,7 +811,6 @@ namespace chaiscript
} else if (!unsigned_ && !longlong_ && u >= std::numeric_limits<long>::min() && u <= std::numeric_limits<long>::max()) { } else if (!unsigned_ && !longlong_ && u >= std::numeric_limits<long>::min() && u <= std::numeric_limits<long>::max()) {
return const_var(static_cast<long>(u)); return const_var(static_cast<long>(u));
} else if ((unsigned_ || base != 10) && !longlong_ } else if ((unsigned_ || base != 10) && !longlong_
&& u >= std::numeric_limits<unsigned long>::min() && u >= std::numeric_limits<unsigned long>::min()
&& u <= std::numeric_limits<unsigned long>::max()) { && u <= std::numeric_limits<unsigned long>::max()) {
return const_var(static_cast<unsigned long>(u)); return const_var(static_cast<unsigned long>(u));
@ -1368,6 +1369,10 @@ namespace chaiscript
} }
} }
if (cparser.saw_interpolation_marker) {
match.push_back('$');
}
return cparser.is_interpolated; return cparser.is_interpolated;
}(); }();
@ -1491,7 +1496,7 @@ namespace chaiscript
return retval; return retval;
} }
bool is_operator(const std::string_view &t_s) const noexcept { bool is_operator(std::string_view t_s) const noexcept {
return m_operator_matches.is_match(t_s); return m_operator_matches.is_match(t_s);
} }

View File

@ -37,7 +37,7 @@ namespace chaiscript {
} }
}; };
typedef Tracer<Noop_Tracer_Detail> Noop_Tracer; using Noop_Tracer = Tracer<Noop_Tracer_Detail>;
} }
} }

View File

@ -52,7 +52,7 @@ namespace chaiscript
static std::string get_error_message(DWORD t_err) static std::string get_error_message(DWORD t_err)
{ {
typedef LPTSTR StringType; using StringType = LPTSTR;
#if defined(_UNICODE) || defined(UNICODE) #if defined(_UNICODE) || defined(UNICODE)
std::wstring retval = L"Unknown Error"; std::wstring retval = L"Unknown Error";

View File

@ -52,7 +52,7 @@ namespace chaiscript
return hash(std::begin(str), std::end(str)-1); return hash(std::begin(str), std::end(str)-1);
} }
static constexpr std::uint32_t hash(const std::string_view &sv) noexcept { static constexpr std::uint32_t hash(std::string_view sv) noexcept {
return hash(sv.begin(), sv.end()); return hash(sv.begin(), sv.end());
} }
@ -67,7 +67,7 @@ namespace chaiscript
std::uint32_t hash = 0; std::uint32_t hash = 0;
while (begin != end) { while (begin != end) {
hash += *begin; hash += std::uint32_t(*begin);
hash += hash << 10; hash += hash << 10;
hash ^= hash >> 6; hash ^= hash >> 6;
++begin; ++begin;
@ -84,7 +84,7 @@ namespace chaiscript
return hash(std::begin(str), std::end(str)-1); return hash(std::begin(str), std::end(str)-1);
} }
static constexpr std::uint32_t hash(const std::string_view &sv) noexcept { static constexpr std::uint32_t hash(std::string_view sv) noexcept {
return hash(sv.begin(), sv.end()); return hash(sv.begin(), sv.end());
} }

View File

@ -36,7 +36,7 @@ namespace chaiscript
return data + m_size; return data + m_size;
} }
constexpr bool operator==(const std::string_view &other) const noexcept { constexpr bool operator==(std::string_view other) const noexcept {
//return std::string_view(data, m_size) == other; //return std::string_view(data, m_size) == other;
auto b1 = begin(); auto b1 = begin();
const auto e1 = end(); const auto e1 = end();

View File

@ -282,19 +282,19 @@ int main(int argc, char *argv[])
#endif #endif
std::vector<std::string> usepaths; std::vector<std::string> usepaths;
usepaths.push_back(""); usepaths.emplace_back("");
if (usepath != nullptr) if (usepath != nullptr)
{ {
usepaths.push_back(usepath); usepaths.emplace_back(usepath);
} }
std::vector<std::string> modulepaths; std::vector<std::string> modulepaths;
std::vector<std::string> searchpaths = default_search_paths(); std::vector<std::string> searchpaths = default_search_paths();
modulepaths.insert(modulepaths.end(), searchpaths.begin(), searchpaths.end()); modulepaths.insert(modulepaths.end(), searchpaths.begin(), searchpaths.end());
modulepaths.push_back(""); modulepaths.emplace_back("");
if (modulepath != nullptr) if (modulepath != nullptr)
{ {
modulepaths.push_back(modulepath); modulepaths.emplace_back(modulepath);
} }
chaiscript::ChaiScript_Basic chai(create_chaiscript_stdlib(),create_chaiscript_parser(),modulepaths,usepaths); chaiscript::ChaiScript_Basic chai(create_chaiscript_stdlib(),create_chaiscript_parser(),modulepaths,usepaths);

View File

@ -91,7 +91,7 @@ int to_int(TestEnum t)
class TestDerivedType : public TestBaseType class TestDerivedType : public TestBaseType
{ {
public: public:
virtual int func() override { return 1; } int func() override { return 1; }
int derived_only_func() { return 19; } int derived_only_func() { return 19; }
}; };

View File

@ -17,9 +17,8 @@ bool run_test_type_conversion(const Boxed_Value &bv, bool expectedpass)
if (expectedpass) { if (expectedpass) {
std::cerr << "Failure in run_test_type_conversion: " << e.what() << '\n'; std::cerr << "Failure in run_test_type_conversion: " << e.what() << '\n';
return false; return false;
} else {
return true;
} }
return true;
} catch (const std::exception &e) { } catch (const std::exception &e) {
std::cerr << "Unexpected standard exception when attempting cast_conversion: " << e.what() << '\n'; std::cerr << "Unexpected standard exception when attempting cast_conversion: " << e.what() << '\n';
return false; return false;
@ -28,12 +27,7 @@ bool run_test_type_conversion(const Boxed_Value &bv, bool expectedpass)
return false; return false;
} }
if (expectedpass) return expectedpass;
{
return true;
} else {
return false;
}
} }
template<typename To> template<typename To>
@ -287,8 +281,6 @@ bool pointer_test(const T& default_value, const T& new_value)
delete p; delete p;
return false; return false;
} }
} }
@ -315,11 +307,9 @@ int main()
// storing a pointer // storing a pointer
passed &= pointer_test<int>(1, 0); passed &= pointer_test<int>(1, 0);
if (passed) if (passed) {
{
return EXIT_SUCCESS; return EXIT_SUCCESS;
} else {
return EXIT_FAILURE;
} }
return EXIT_FAILURE;
} }

File diff suppressed because it is too large Load Diff

View File

@ -795,7 +795,7 @@ struct Object_Lifetime_Vector2
{ {
Object_Lifetime_Vector2() : x(0), y(0) {} Object_Lifetime_Vector2() : x(0), y(0) {}
Object_Lifetime_Vector2(T px, T py) : x(px), y(py) {} Object_Lifetime_Vector2(T px, T py) : x(px), y(py) {}
Object_Lifetime_Vector2(const Object_Lifetime_Vector2& cp) : x(cp.x), y(cp.y) {} Object_Lifetime_Vector2(const Object_Lifetime_Vector2& cp) noexcept : x(cp.x), y(cp.y) {}
Object_Lifetime_Vector2& operator+=(const Object_Lifetime_Vector2& vec_r) Object_Lifetime_Vector2& operator+=(const Object_Lifetime_Vector2& vec_r)
{ {
@ -1073,7 +1073,7 @@ struct Count_Tracer
TEST_CASE("Test count tracer") TEST_CASE("Test count tracer")
{ {
typedef chaiscript::parser::ChaiScript_Parser< chaiscript::eval::Tracer<Count_Tracer>, chaiscript::optimizer::Optimizer_Default > Parser_Type; using Parser_Type = chaiscript::parser::ChaiScript_Parser< chaiscript::eval::Tracer<Count_Tracer>, chaiscript::optimizer::Optimizer_Default >;
chaiscript::ChaiScript_Basic chai(chaiscript::Std_Lib::library(), chaiscript::ChaiScript_Basic chai(chaiscript::Std_Lib::library(),
std::make_unique<Parser_Type>()); std::make_unique<Parser_Type>());
@ -1341,14 +1341,15 @@ TEST_CASE("Test reference member being registered")
CHECK(d == Approx(2.3)); CHECK(d == Approx(2.3));
} }
// starting with C++20 u8"" strings cannot be compared with std::string
// and the support for std::u8strings is still terrible.
TEST_CASE("Test unicode matches C++") TEST_CASE("Test unicode matches C++")
{ {
chaiscript::ChaiScript_Basic chai(create_chaiscript_stdlib(),create_chaiscript_parser()); chaiscript::ChaiScript_Basic chai(create_chaiscript_stdlib(), create_chaiscript_parser());
CHECK(u8"\U000000AC" == chai.eval<std::string>(R"("\U000000AC")")); CHECK("\U000000AC" == chai.eval<std::string>(R"("\U000000AC")"));
CHECK("\xF0\x9F\x8D\x8C" == chai.eval<std::string>(R"("\xF0\x9F\x8D\x8C")")); CHECK("\xF0\x9F\x8D\x8C" == chai.eval<std::string>(R"("\xF0\x9F\x8D\x8C")"));
CHECK(u8"\U0001F34C" == chai.eval<std::string>(R"("\U0001F34C")")); CHECK("\U0001F34C" == chai.eval<std::string>(R"("\U0001F34C")"));
CHECK(u8"\u2022" == chai.eval<std::string>(R"("\u2022")")); CHECK("\u2022" == chai.eval<std::string>(R"("\u2022")"));
} }
@ -1406,7 +1407,7 @@ TEST_CASE("Throw an exception when trying to add same conversion twice")
{ {
struct my_int { struct my_int {
int value; int value;
my_int(int val): value(val) {}; my_int(int val): value(val) {}
}; };
chaiscript::ChaiScript chai; chaiscript::ChaiScript chai;
@ -1418,7 +1419,45 @@ TEST_CASE("Throw an exception when trying to add same conversion twice")
std::cout << "My_int type conversion 2\n"; std::cout << "My_int type conversion 2\n";
return my_int(x); return my_int(x);
})), chaiscript::exception::conversion_error); })), chaiscript::exception::conversion_error);
} }
TEST_CASE("Test if non copyable/movable types can be registered")
{
struct Noncopyable {
Noncopyable() {str = "test";}
Noncopyable(const Noncopyable&) = delete;
Noncopyable& operator=(const Noncopyable&) = delete;
std::string str;
};
struct Nonmovable {
Nonmovable() {str = "test";}
Nonmovable(Nonmovable&&) = delete;
Nonmovable& operator=(Nonmovable&&) = delete;
std::string str;
};
struct Nothing {
Nothing() {str = "test";}
Nothing(Nothing&&) = delete;
Nothing& operator=(Nothing&&) = delete;
Nothing(const Nothing&) = delete;
Nothing& operator=(const Nothing&) = delete;
std::string str;
};
chaiscript::ChaiScript chai;
chai.add(chaiscript::user_type<Noncopyable>(), "Noncopyable");
chai.add(chaiscript::constructor<Noncopyable()>(), "Noncopyable");
chai.add(chaiscript::user_type<Nonmovable>(), "Nonmovable");
chai.add(chaiscript::constructor<Nonmovable()>(), "Nonmovable");
chai.add(chaiscript::user_type<Nothing>(), "Nothing");
chai.add(chaiscript::constructor<Nothing()>(), "Nothing");
}

View File

@ -2,3 +2,7 @@ assert_equal("\$ {4 + 5}", "$ {4 + 5}")
assert_equal("\$9", "$${4+5}") assert_equal("\$9", "$${4+5}")
assert_equal("Value: \${4 + 5}", "Value: \${4 + 5}") assert_equal("Value: \${4 + 5}", "Value: \${4 + 5}")
assert_equal("Value: \$9", "Value: \$${4 + 5}") assert_equal("Value: \$9", "Value: \$${4 + 5}")
assert_equal("\$code\$", "$code$")
assert_equal("\$\$", "$$")
assert_equal("\$", "$")
assert_equal("\${", "\${") // ensure this doesn't fail

View File

@ -25,9 +25,8 @@ bool test_literal(T val, const std::string &str, bool use_boxed_number = false)
T val2 = [&](){ T val2 = [&](){
if (!use_boxed_number) { if (!use_boxed_number) {
return chai.eval<T>(str); return chai.eval<T>(str);
} else {
return chai.eval<chaiscript::Boxed_Number>(str).get_as_checked<T>();
} }
return chai.eval<chaiscript::Boxed_Number>(str).get_as_checked<T>();
}(); }();
std::cout << "' chai '" << val2 << "'\n"; std::cout << "' chai '" << val2 << "'\n";
@ -272,10 +271,9 @@ int main()
) )
{ {
return EXIT_SUCCESS; return EXIT_SUCCESS;
} else {
return EXIT_FAILURE;
} }
return EXIT_FAILURE;
} }

View File

@ -2,9 +2,7 @@
#include "multifile_test_module.hpp" #include "multifile_test_module.hpp"
Multi_Test_Module::Multi_Test_Module() Multi_Test_Module::Multi_Test_Module() noexcept = default;
{
}
int Multi_Test_Module::get_module_value() int Multi_Test_Module::get_module_value()
{ {

View File

@ -5,7 +5,7 @@ class Multi_Test_Module
public: public:
static int get_module_value(); static int get_module_value();
Multi_Test_Module(); Multi_Test_Module() noexcept;
chaiscript::ModulePtr get_module(); chaiscript::ModulePtr get_module();
}; };

View File

@ -53,10 +53,10 @@ int main()
#endif #endif
std::vector<std::string> usepaths; std::vector<std::string> usepaths;
usepaths.push_back(""); usepaths.emplace_back("");
if (usepath) if (usepath)
{ {
usepaths.push_back(usepath); usepaths.emplace_back(usepath);
} }
std::vector<std::string> modulepaths; std::vector<std::string> modulepaths;
@ -64,10 +64,10 @@ int main()
#ifdef CHAISCRIPT_NO_DYNLOAD #ifdef CHAISCRIPT_NO_DYNLOAD
chaiscript::ChaiScript chai(/* unused */modulepaths, usepaths); chaiscript::ChaiScript chai(/* unused */modulepaths, usepaths);
#else #else
modulepaths.push_back(""); modulepaths.emplace_back("");
if (modulepath) if (modulepath)
{ {
modulepaths.push_back(modulepath); modulepaths.emplace_back(modulepath);
} }
// For this test we are going to load the dynamic stdlib // For this test we are going to load the dynamic stdlib