Merge branch 'feature_enum_utility_helper' into Fix_Crash_From_CppCon
This commit is contained in:
@@ -961,15 +961,6 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
void parse(const char_type t_char, const int line, const int col, const std::string &filename) {
|
void parse(const char_type t_char, const int line, const int col, const std::string &filename) {
|
||||||
if (t_char == '\\') {
|
|
||||||
if (is_escaped) {
|
|
||||||
match.push_back('\\');
|
|
||||||
is_escaped = false;
|
|
||||||
} else {
|
|
||||||
is_escaped = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (is_escaped) {
|
|
||||||
const bool is_octal_char = t_char >= '0' && t_char <= '7';
|
const bool is_octal_char = t_char >= '0' && t_char <= '7';
|
||||||
|
|
||||||
if (is_octal) {
|
if (is_octal) {
|
||||||
@@ -979,9 +970,9 @@ namespace chaiscript
|
|||||||
if (octal_matches.size() == 3) {
|
if (octal_matches.size() == 3) {
|
||||||
process_octal();
|
process_octal();
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
process_octal();
|
process_octal();
|
||||||
match.push_back(t_char);
|
|
||||||
}
|
}
|
||||||
} else if (is_hex) {
|
} else if (is_hex) {
|
||||||
const bool is_hex_char = (t_char >= '0' && t_char <= '9')
|
const bool is_hex_char = (t_char >= '0' && t_char <= '9')
|
||||||
@@ -990,11 +981,30 @@ namespace chaiscript
|
|||||||
|
|
||||||
if (is_hex_char) {
|
if (is_hex_char) {
|
||||||
hex_matches.push_back(t_char);
|
hex_matches.push_back(t_char);
|
||||||
|
|
||||||
|
if (hex_matches.size() == 2*sizeof(char_type)) {
|
||||||
|
// This rule differs from the C/C++ standard, but ChaiScript
|
||||||
|
// does not offer the same workaround options, and having
|
||||||
|
// hexadecimal sequences longer than can fit into the char
|
||||||
|
// type is undefined behavior anyway.
|
||||||
|
process_hex();
|
||||||
|
}
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
process_hex();
|
process_hex();
|
||||||
match.push_back(t_char);
|
|
||||||
}
|
}
|
||||||
} else if (is_octal_char) {
|
}
|
||||||
|
|
||||||
|
if (t_char == '\\') {
|
||||||
|
if (is_escaped) {
|
||||||
|
match.push_back('\\');
|
||||||
|
is_escaped = false;
|
||||||
|
} else {
|
||||||
|
is_escaped = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (is_escaped) {
|
||||||
|
if (is_octal_char) {
|
||||||
is_octal = true;
|
is_octal = true;
|
||||||
octal_matches.push_back(t_char);
|
octal_matches.push_back(t_char);
|
||||||
} else if (t_char == 'x') {
|
} else if (t_char == 'x') {
|
||||||
|
@@ -421,22 +421,22 @@ class JSON
|
|||||||
Class Type;
|
Class Type;
|
||||||
};
|
};
|
||||||
|
|
||||||
JSON Array() {
|
inline JSON Array() {
|
||||||
return JSON::Make( JSON::Class::Array );
|
return JSON::Make( JSON::Class::Array );
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
JSON Array( T... args ) {
|
inline JSON Array( T... args ) {
|
||||||
JSON arr = JSON::Make( JSON::Class::Array );
|
JSON arr = JSON::Make( JSON::Class::Array );
|
||||||
arr.append( args... );
|
arr.append( args... );
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSON Object() {
|
inline JSON Object() {
|
||||||
return JSON::Make( JSON::Class::Object );
|
return JSON::Make( JSON::Class::Object );
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& operator<<( std::ostream &os, const JSON &json ) {
|
inline std::ostream& operator<<( std::ostream &os, const JSON &json ) {
|
||||||
os << json.dump();
|
os << json.dump();
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
@@ -636,7 +636,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JSON JSON::Load( const string &str ) {
|
inline JSON JSON::Load( const string &str ) {
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
return parse_next( str, offset );
|
return parse_next( str, offset );
|
||||||
}
|
}
|
||||||
|
@@ -8,12 +8,14 @@
|
|||||||
#define CHAISCRIPT_UTILITY_UTILITY_HPP_
|
#define CHAISCRIPT_UTILITY_UTILITY_HPP_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "../chaiscript.hpp"
|
#include "../chaiscript.hpp"
|
||||||
#include "../dispatchkit/proxy_functions.hpp"
|
#include "../dispatchkit/proxy_functions.hpp"
|
||||||
#include "../dispatchkit/type_info.hpp"
|
#include "../dispatchkit/type_info.hpp"
|
||||||
|
#include "../dispatchkit/operators.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
@@ -62,6 +64,32 @@ namespace chaiscript
|
|||||||
t_module.add(fun.first, fun.second);
|
t_module.add(fun.first, fun.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Enum, typename ModuleType>
|
||||||
|
typename std::enable_if<std::is_enum<Enum>::value, void>::type
|
||||||
|
add_class(ModuleType &t_module,
|
||||||
|
const std::string &t_class_name,
|
||||||
|
const std::vector<std::pair<typename std::underlying_type<Enum>::type, std::string>> &t_constants)
|
||||||
|
{
|
||||||
|
t_module.add(chaiscript::user_type<Enum>(), t_class_name);
|
||||||
|
|
||||||
|
t_module.add(chaiscript::constructor<Enum ()>(), t_class_name);
|
||||||
|
t_module.add(chaiscript::constructor<Enum (const Enum &)>(), t_class_name);
|
||||||
|
|
||||||
|
t_module.add([](){
|
||||||
|
// add some comparison and assignment operators
|
||||||
|
using namespace chaiscript::bootstrap::operators;
|
||||||
|
return assign<Enum>(not_equal<Enum>(equal<Enum>()));
|
||||||
|
}());
|
||||||
|
|
||||||
|
t_module.add(chaiscript::fun([](const Enum &e, const typename std::underlying_type<Enum>::type &i) { return e == i; }), "==");
|
||||||
|
t_module.add(chaiscript::fun([](const typename std::underlying_type<Enum>::type &i, const Enum &e) { return i == e; }), "==");
|
||||||
|
|
||||||
|
for (const auto &constant : t_constants)
|
||||||
|
{
|
||||||
|
t_module.add_global_const(chaiscript::const_var(Enum(constant.first)), constant.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
// caught in other cpp files if chaiscript causes them
|
// caught in other cpp files if chaiscript causes them
|
||||||
|
|
||||||
#include <chaiscript/utility/utility.hpp>
|
#include <chaiscript/utility/utility.hpp>
|
||||||
|
#include <chaiscript/dispatchkit/bootstrap_stl.hpp>
|
||||||
|
|
||||||
#ifdef CHAISCRIPT_MSVC
|
#ifdef CHAISCRIPT_MSVC
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
@@ -518,6 +519,65 @@ TEST_CASE("Utility_Test utility class wrapper")
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
enum Utility_Test_Numbers
|
||||||
|
{
|
||||||
|
ONE,
|
||||||
|
TWO,
|
||||||
|
THREE
|
||||||
|
};
|
||||||
|
|
||||||
|
void do_something_with_enum_vector(const std::vector<Utility_Test_Numbers> &v)
|
||||||
|
{
|
||||||
|
CHECK(v.size() == 3);
|
||||||
|
CHECK(v[0] == ONE);
|
||||||
|
CHECK(v[1] == THREE);
|
||||||
|
CHECK(v[2] == TWO);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Utility_Test utility class wrapper for enum")
|
||||||
|
{
|
||||||
|
|
||||||
|
chaiscript::ModulePtr m = chaiscript::ModulePtr(new chaiscript::Module());
|
||||||
|
|
||||||
|
using namespace chaiscript;
|
||||||
|
|
||||||
|
chaiscript::utility::add_class<Utility_Test_Numbers>(*m,
|
||||||
|
"Utility_Test_Numbers",
|
||||||
|
{ { ONE, "ONE" },
|
||||||
|
{ TWO, "TWO" },
|
||||||
|
{ THREE, "THREE" }
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
chaiscript::ChaiScript chai;
|
||||||
|
chai.add(m);
|
||||||
|
|
||||||
|
CHECK(chai.eval<Utility_Test_Numbers>("ONE ") == 0);
|
||||||
|
CHECK(chai.eval<Utility_Test_Numbers>("TWO ") == 1);
|
||||||
|
CHECK(chai.eval<Utility_Test_Numbers>("THREE ") == 2);
|
||||||
|
|
||||||
|
CHECK(chai.eval<bool>("ONE == 0"));
|
||||||
|
|
||||||
|
chai.add(chaiscript::fun(&do_something_with_enum_vector), "do_something_with_enum_vector");
|
||||||
|
chai.add(chaiscript::vector_conversion<std::vector<Utility_Test_Numbers>>());
|
||||||
|
CHECK_NOTHROW(chai.eval("var a = [ONE, TWO, THREE]"));
|
||||||
|
CHECK_NOTHROW(chai.eval("do_something_with_enum_vector([ONE, THREE, TWO])"));
|
||||||
|
CHECK_NOTHROW(chai.eval("[ONE]"));
|
||||||
|
|
||||||
|
const auto v = chai.eval<std::vector<Utility_Test_Numbers>>("a");
|
||||||
|
CHECK(v.size() == 3);
|
||||||
|
CHECK(v.at(1) == TWO);
|
||||||
|
|
||||||
|
CHECK(chai.eval<bool>("ONE == ONE"));
|
||||||
|
CHECK(chai.eval<bool>("ONE != TWO"));
|
||||||
|
CHECK_NOTHROW(chai.eval("var o = ONE; o = TWO"));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////// Object copy count test
|
////// Object copy count test
|
||||||
|
|
||||||
class Object_Copy_Count_Test
|
class Object_Copy_Count_Test
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
assert_equal("\x39", "9")
|
assert_equal("\x39", "9")
|
||||||
assert_equal("\x039", "9")
|
assert_equal("\x39ec", "9ec")
|
||||||
assert_equal("\x39g", "9g")
|
assert_equal("\x39g", "9g")
|
||||||
assert_equal("b\x39g", "b9g")
|
assert_equal("b\x39g", "b9g")
|
||||||
|
assert_equal("\x39\x38g", "98g")
|
||||||
|
|
||||||
|
@@ -3,4 +3,5 @@ assert_equal("\71", "9")
|
|||||||
assert_equal("\071", "9")
|
assert_equal("\071", "9")
|
||||||
assert_equal("\71a", "9a")
|
assert_equal("\71a", "9a")
|
||||||
assert_equal("b\71a", "b9a")
|
assert_equal("b\71a", "b9a")
|
||||||
|
assert_equal("\71\70a", "98a")
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user