mirror of
https://github.com/ChaiScript/ChaiScript.git
synced 2026-02-06 01:39:56 +08:00
Move to QuickFlatMap from manual vector map thing
This commit is contained in:
parent
b47fec2f71
commit
48e5a46cbd
@ -36,6 +36,7 @@
|
|||||||
#include "proxy_functions.hpp"
|
#include "proxy_functions.hpp"
|
||||||
#include "type_info.hpp"
|
#include "type_info.hpp"
|
||||||
#include "short_alloc.hpp"
|
#include "short_alloc.hpp"
|
||||||
|
#include "../utility/quick_flat_map.hpp"
|
||||||
|
|
||||||
namespace chaiscript {
|
namespace chaiscript {
|
||||||
class Boxed_Number;
|
class Boxed_Number;
|
||||||
@ -388,7 +389,7 @@ namespace chaiscript
|
|||||||
using SmallVector = std::vector<T>;
|
using SmallVector = std::vector<T>;
|
||||||
|
|
||||||
|
|
||||||
using Scope = SmallVector<std::pair<std::string, Boxed_Value>>;
|
using Scope = utility::QuickFlatMap<std::string, Boxed_Value>;
|
||||||
using StackData = SmallVector<Scope>;
|
using StackData = SmallVector<Scope>;
|
||||||
using Stacks = SmallVector<StackData>;
|
using Stacks = SmallVector<StackData>;
|
||||||
using Call_Param_List = SmallVector<Boxed_Value>;
|
using Call_Param_List = SmallVector<Boxed_Value>;
|
||||||
@ -409,24 +410,13 @@ namespace chaiscript
|
|||||||
void push_stack()
|
void push_stack()
|
||||||
{
|
{
|
||||||
stacks.emplace_back(1);
|
stacks.emplace_back(1);
|
||||||
// stacks.emplace_back(StackData(1, Scope(scope_allocator), stack_data_allocator));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void push_call_params()
|
void push_call_params()
|
||||||
{
|
{
|
||||||
call_params.emplace_back();
|
call_params.emplace_back();
|
||||||
// call_params.emplace_back(Call_Param_List(call_param_list_allocator));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Scope::allocator_type::arena_type scope_allocator;
|
|
||||||
//StackData::allocator_type::arena_type stack_data_allocator;
|
|
||||||
//Stacks::allocator_type::arena_type stacks_allocator;
|
|
||||||
//Call_Param_List::allocator_type::arena_type call_param_list_allocator;
|
|
||||||
//Call_Params::allocator_type::arena_type call_params_allocator;
|
|
||||||
|
|
||||||
// Stacks stacks = Stacks(stacks_allocator);
|
|
||||||
// Call_Params call_params = Call_Params(call_params_allocator);
|
|
||||||
|
|
||||||
Stacks stacks;
|
Stacks stacks;
|
||||||
Call_Params call_params;
|
Call_Params call_params;
|
||||||
|
|
||||||
@ -440,7 +430,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
using Type_Name_Map = std::map<std::string, chaiscript::Type_Info, str_less>;
|
using Type_Name_Map = std::map<std::string, chaiscript::Type_Info, str_less>;
|
||||||
using Scope = std::vector<std::pair<std::string, Boxed_Value>>;
|
using Scope = utility::QuickFlatMap<std::string, Boxed_Value>;
|
||||||
using StackData = Stack_Holder::StackData;
|
using StackData = Stack_Holder::StackData;
|
||||||
|
|
||||||
struct State
|
struct State
|
||||||
@ -486,12 +476,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
for (auto stack_elem = stack.rbegin(); stack_elem != stack.rend(); ++stack_elem)
|
for (auto stack_elem = stack.rbegin(); stack_elem != stack.rend(); ++stack_elem)
|
||||||
{
|
{
|
||||||
auto itr = std::find_if(stack_elem->begin(), stack_elem->end(),
|
if (auto itr = stack_elem->find(name); itr != stack_elem->end())
|
||||||
[&](const std::pair<std::string, Boxed_Value> &o) {
|
|
||||||
return o.first == name;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (itr != stack_elem->end())
|
|
||||||
{
|
{
|
||||||
itr->second = std::move(obj);
|
itr->second = std::move(obj);
|
||||||
return;
|
return;
|
||||||
@ -504,38 +489,32 @@ namespace chaiscript
|
|||||||
/// Adds a named object to the current scope
|
/// Adds a named object to the current scope
|
||||||
/// \warning This version does not check the validity of the name
|
/// \warning This version does not check the validity of the name
|
||||||
/// it is meant for internal use only
|
/// it is meant for internal use only
|
||||||
Boxed_Value &add_get_object(const std::string &t_name, Boxed_Value obj, Stack_Holder &t_holder)
|
Boxed_Value &add_get_object(std::string t_name, Boxed_Value obj, Stack_Holder &t_holder)
|
||||||
{
|
{
|
||||||
auto &stack_elem = get_stack_data(t_holder).back();
|
auto &stack_elem = get_stack_data(t_holder).back();
|
||||||
|
|
||||||
if (std::any_of(stack_elem.begin(), stack_elem.end(),
|
if (auto result = stack_elem.insert(std::pair{std::move(t_name), std::move(obj)}); result.second)
|
||||||
[&](const std::pair<std::string, Boxed_Value> &o) {
|
|
||||||
return o.first == t_name;
|
|
||||||
}))
|
|
||||||
{
|
{
|
||||||
throw chaiscript::exception::name_conflict_error(t_name);
|
return result.first->second;
|
||||||
|
} else {
|
||||||
|
//insert failed
|
||||||
|
throw chaiscript::exception::name_conflict_error(result.first->first);
|
||||||
}
|
}
|
||||||
|
|
||||||
return stack_elem.emplace_back(t_name, std::move(obj)).second;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Adds a named object to the current scope
|
/// Adds a named object to the current scope
|
||||||
/// \warning This version does not check the validity of the name
|
/// \warning This version does not check the validity of the name
|
||||||
/// it is meant for internal use only
|
/// it is meant for internal use only
|
||||||
void add_object(const std::string &t_name, Boxed_Value obj, Stack_Holder &t_holder)
|
void add_object(std::string t_name, Boxed_Value obj, Stack_Holder &t_holder)
|
||||||
{
|
{
|
||||||
auto &stack_elem = get_stack_data(t_holder).back();
|
auto &stack_elem = get_stack_data(t_holder).back();
|
||||||
|
|
||||||
if (std::any_of(stack_elem.begin(), stack_elem.end(),
|
if (auto result = stack_elem.insert(std::pair{std::move(t_name), std::move(obj)}); !result.second)
|
||||||
[&](const std::pair<std::string, Boxed_Value> &o) {
|
|
||||||
return o.first == t_name;
|
|
||||||
}))
|
|
||||||
{
|
{
|
||||||
throw chaiscript::exception::name_conflict_error(t_name);
|
//insert failed
|
||||||
|
throw chaiscript::exception::name_conflict_error(result.first->first);
|
||||||
}
|
}
|
||||||
|
|
||||||
stack_elem.emplace_back(t_name, std::move(obj));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -566,46 +545,30 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a new global (non-const) shared object, between all the threads
|
/// Adds a new global (non-const) shared object, between all the threads
|
||||||
Boxed_Value add_global_no_throw(const Boxed_Value &obj, const std::string &name)
|
Boxed_Value add_global_no_throw(Boxed_Value obj, std::string name)
|
||||||
{
|
{
|
||||||
chaiscript::detail::threading::unique_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
|
chaiscript::detail::threading::unique_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
|
||||||
|
|
||||||
const auto itr = m_state.m_global_objects.find(name);
|
return m_state.m_global_objects.insert(std::pair{std::move(name), std::move(obj)}).first->second;
|
||||||
if (itr == m_state.m_global_objects.end())
|
|
||||||
{
|
|
||||||
m_state.m_global_objects.insert(std::make_pair(name, obj));
|
|
||||||
return obj;
|
|
||||||
} else {
|
|
||||||
return itr->second;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Adds a new global (non-const) shared object, between all the threads
|
/// Adds a new global (non-const) shared object, between all the threads
|
||||||
void add_global(const Boxed_Value &obj, const std::string &name)
|
void add_global(Boxed_Value obj, std::string name)
|
||||||
{
|
{
|
||||||
chaiscript::detail::threading::unique_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
|
chaiscript::detail::threading::unique_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
|
||||||
|
|
||||||
if (m_state.m_global_objects.find(name) != m_state.m_global_objects.end())
|
if (auto result = m_state.m_global_objects.insert(std::pair{std::move(name), std::move(obj)}); !result.second) {
|
||||||
{
|
// insert failed
|
||||||
throw chaiscript::exception::name_conflict_error(name);
|
throw chaiscript::exception::name_conflict_error(result.first->first);
|
||||||
} else {
|
|
||||||
m_state.m_global_objects.insert(std::make_pair(name, obj));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Updates an existing global shared object or adds a new global shared object if not found
|
/// Updates an existing global shared object or adds a new global shared object if not found
|
||||||
void set_global(const Boxed_Value &obj, const std::string &name)
|
void set_global(Boxed_Value obj, std::string name)
|
||||||
{
|
{
|
||||||
chaiscript::detail::threading::unique_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
|
chaiscript::detail::threading::unique_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
|
||||||
|
m_state.m_global_objects.insert_or_assign(std::move(name), std::move(obj));
|
||||||
const auto itr = m_state.m_global_objects.find(name);
|
|
||||||
if (itr != m_state.m_global_objects.end())
|
|
||||||
{
|
|
||||||
itr->second.assign(obj);
|
|
||||||
} else {
|
|
||||||
m_state.m_global_objects.insert(std::make_pair(name, obj));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a new scope to the stack
|
/// Adds a new scope to the stack
|
||||||
@ -688,7 +651,7 @@ namespace chaiscript
|
|||||||
} else if ((loc & static_cast<uint_fast32_t>(Loc::is_local)) != 0u) {
|
} else if ((loc & static_cast<uint_fast32_t>(Loc::is_local)) != 0u) {
|
||||||
auto &stack = get_stack_data(t_holder);
|
auto &stack = get_stack_data(t_holder);
|
||||||
|
|
||||||
return stack[stack.size() - 1 - ((loc & static_cast<uint_fast32_t>(Loc::stack_mask)) >> 16)][loc & static_cast<uint_fast32_t>(Loc::loc_mask)].second;
|
return stack[stack.size() - 1 - ((loc & static_cast<uint_fast32_t>(Loc::stack_mask)) >> 16)].at_index(loc & static_cast<uint_fast32_t>(Loc::loc_mask));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is the value we are looking for a global or function?
|
// Is the value we are looking for a global or function?
|
||||||
|
|||||||
@ -35,6 +35,14 @@ namespace chaiscript::utility {
|
|||||||
return data.end();
|
return data.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto &back() noexcept {
|
||||||
|
return data.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto &back() const noexcept {
|
||||||
|
return data.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Value &operator[](const Key &s) {
|
Value &operator[](const Key &s) {
|
||||||
const auto itr = find(s);
|
const auto itr = find(s);
|
||||||
@ -45,6 +53,27 @@ namespace chaiscript::utility {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value &at_index(const std::size_t idx) noexcept
|
||||||
|
{
|
||||||
|
return data[idx].second;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Value &at_index(const std::size_t idx) const noexcept
|
||||||
|
{
|
||||||
|
return data[idx].second;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool empty() const noexcept
|
||||||
|
{
|
||||||
|
return data.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Itr>
|
||||||
|
void assign(Itr begin, Itr end)
|
||||||
|
{
|
||||||
|
data.assign(begin, end);
|
||||||
|
}
|
||||||
|
|
||||||
Value &at(const Key &s) {
|
Value &at(const Key &s) {
|
||||||
const auto itr = find(s);
|
const auto itr = find(s);
|
||||||
if (itr != data.end()) {
|
if (itr != data.end()) {
|
||||||
@ -54,6 +83,30 @@ namespace chaiscript::utility {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename M>
|
||||||
|
auto insert_or_assign(Key &&key, M &&m)
|
||||||
|
{
|
||||||
|
if (auto itr = find(key); itr != data.end()) {
|
||||||
|
*itr = std::forward<M>(m);
|
||||||
|
return std::pair{itr, false};
|
||||||
|
} else {
|
||||||
|
return std::pair{data.emplace(itr, std::move(key), std::forward<M>(m)), true};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename M>
|
||||||
|
auto insert_or_assign(const Key &key, M &&m)
|
||||||
|
{
|
||||||
|
if (auto itr = find(key); itr != data.end()) {
|
||||||
|
*itr = std::forward<M>(m);
|
||||||
|
return std::pair{itr, false};
|
||||||
|
} else {
|
||||||
|
return std::pair{data.emplace(itr, key, std::forward<M>(m)), true};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const Value &at(const Key &s) const {
|
const Value &at(const Key &s) const {
|
||||||
const auto itr = find(s);
|
const auto itr = find(s);
|
||||||
if (itr != data.end()) {
|
if (itr != data.end()) {
|
||||||
@ -69,9 +122,18 @@ namespace chaiscript::utility {
|
|||||||
|
|
||||||
std::vector<std::pair<Key, Value>> data;
|
std::vector<std::pair<Key, Value>> data;
|
||||||
|
|
||||||
|
using value_type = std::pair<Key, Value>;
|
||||||
using iterator = typename decltype(data)::iterator;
|
using iterator = typename decltype(data)::iterator;
|
||||||
using const_iterator = typename decltype(data)::const_iterator;
|
using const_iterator = typename decltype(data)::const_iterator;
|
||||||
|
|
||||||
|
std::pair<iterator,bool> insert( value_type&& value )
|
||||||
|
{
|
||||||
|
if (const auto itr = find(value.first); itr != data.end()) {
|
||||||
|
return std::pair{itr, false};
|
||||||
|
} else {
|
||||||
|
return std::pair{data.insert(itr, std::move(value)), true};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user