TypeDef append from vector<>
This commit is contained in:
+62
-5
@@ -188,6 +188,9 @@ private:
|
||||
std::vector<Member> children;
|
||||
friend class TypeDef;
|
||||
friend class client::detail::CommonBase;
|
||||
|
||||
PVXS_API
|
||||
void _validate() const;
|
||||
public:
|
||||
struct Helper;
|
||||
|
||||
@@ -198,13 +201,29 @@ public:
|
||||
:Member(code, name, {})
|
||||
{}
|
||||
//! Compound member with type ID
|
||||
PVXS_API
|
||||
Member(TypeCode code, const std::string& name, const std::string& id, std::initializer_list<Member> children);
|
||||
Member(TypeCode code, const std::string& name, const std::string& id, std::initializer_list<Member> children)
|
||||
:code(code)
|
||||
,name(name)
|
||||
,id(id)
|
||||
,children(children.begin(), children.end())
|
||||
{_validate();}
|
||||
template<typename Iterable>
|
||||
Member(TypeCode code, const std::string& name, const std::string& id, const Iterable& children)
|
||||
:code(code)
|
||||
,name(name)
|
||||
,id(id)
|
||||
,children(children.begin(), children.end())
|
||||
{_validate();}
|
||||
//! Compound member without type ID
|
||||
inline
|
||||
Member(TypeCode code, const std::string& name, std::initializer_list<Member> children)
|
||||
:Member(code, name , std::string(), children)
|
||||
{}
|
||||
template<typename Iterable>
|
||||
inline
|
||||
Member(TypeCode code, const std::string& name, const Iterable& children)
|
||||
:Member(code, name , std::string(), children)
|
||||
{}
|
||||
|
||||
PVXS_API
|
||||
void addChild(const Member& mem);
|
||||
@@ -250,7 +269,11 @@ CASE(AnyA)
|
||||
|
||||
#define CASE(TYPE) \
|
||||
inline Member TYPE(const std::string& name, std::initializer_list<Member> children) { return Member(TypeCode::TYPE, name, children); } \
|
||||
inline Member TYPE(const std::string& name, const std::string& id, std::initializer_list<Member> children) { return Member(TypeCode::TYPE, name, id, children); }
|
||||
template <typename Iterable> \
|
||||
inline Member TYPE(const std::string& name, const Iterable& children) { return Member(TypeCode::TYPE, name, children); } \
|
||||
inline Member TYPE(const std::string& name, const std::string& id, std::initializer_list<Member> children) { return Member(TypeCode::TYPE, name, id, children); } \
|
||||
template <typename Iterable> \
|
||||
inline Member TYPE(const std::string& name, const std::string& id, const Iterable& children) { return Member(TypeCode::TYPE, name, id, children); }
|
||||
|
||||
CASE(Struct)
|
||||
CASE(Union)
|
||||
@@ -294,7 +317,16 @@ public:
|
||||
~TypeDef();
|
||||
|
||||
//! new definition with id and children. code must be TypeCode::Struct or TypeCode::Union
|
||||
TypeDef(TypeCode code, const std::string& id, std::initializer_list<Member> children);
|
||||
template<typename Iterable>
|
||||
TypeDef(TypeCode code, const std::string& id, const Iterable& children)
|
||||
:TypeDef(std::make_shared<Member>(code, "", id, children))
|
||||
{}
|
||||
TypeDef(TypeCode code, const std::string& id, std::initializer_list<Member> children)
|
||||
:TypeDef(std::make_shared<Member>(code, "", id, children))
|
||||
{}
|
||||
private:
|
||||
TypeDef(std::shared_ptr<const Member>&&);
|
||||
public:
|
||||
//! new definition for a single scalar field. code must __not__ be TypeCode::Struct or TypeCode::Union
|
||||
TypeDef(TypeCode code)
|
||||
:TypeDef(code, std::string(), {})
|
||||
@@ -304,8 +336,33 @@ public:
|
||||
:TypeDef(code, std::string(), children)
|
||||
{}
|
||||
|
||||
Member as(const std::string& name) const;
|
||||
|
||||
private:
|
||||
std::shared_ptr<Member> _append_start();
|
||||
static
|
||||
void _append(Member& edit, const Member& mem);
|
||||
void _append_finish(std::shared_ptr<Member>&& edit);
|
||||
public:
|
||||
|
||||
//! append additional children. Only for TypeCode::Struct or TypeCode::Union
|
||||
TypeDef& operator+=(std::initializer_list<Member> children);
|
||||
template<typename Iterable>
|
||||
TypeDef& operator+=(const Iterable& children) {
|
||||
auto edit = _append_start();
|
||||
for(auto& child : children) {
|
||||
_append(edit, child);
|
||||
}
|
||||
_append_finish(std::move(edit));
|
||||
return *this;
|
||||
}
|
||||
TypeDef& operator+=(std::initializer_list<Member> children) {
|
||||
auto edit = _append_start();
|
||||
for(auto& child : children) {
|
||||
_append(*edit, child);
|
||||
}
|
||||
_append_finish(std::move(edit));
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Instanciate this definition
|
||||
Value create() const;
|
||||
|
||||
+31
-28
@@ -22,8 +22,6 @@ struct Member::Helper {
|
||||
static
|
||||
void copy_tree(const FieldDesc* desc, Member& node);
|
||||
static
|
||||
void append_tree(Member& node, const Member& adopt);
|
||||
static
|
||||
void show_Node(std::ostream& strm, const std::string& name, const Member* node, unsigned level=0);
|
||||
};
|
||||
|
||||
@@ -161,14 +159,12 @@ void name_validate(const char *name)
|
||||
}
|
||||
}
|
||||
|
||||
Member::Member(TypeCode code, const std::string& name, const std::string& id, std::initializer_list<Member> children)
|
||||
:code(code), name(name), id(id)
|
||||
void Member::_validate() const
|
||||
{
|
||||
if(!name.empty())
|
||||
name_validate(name.c_str());
|
||||
for(auto& child : children) {
|
||||
Helper::node_validate(this, child.id, child.code);
|
||||
this->children.push_back(child);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,10 +229,8 @@ void Member::Helper::build_tree(std::vector<FieldDesc>& desc, const Member& node
|
||||
assert(desc.size()==index+desc[index].size());
|
||||
}
|
||||
|
||||
TypeDef::TypeDef(TypeCode code, const std::string& id, std::initializer_list<Member> children)
|
||||
TypeDef::TypeDef(std::shared_ptr<const Member>&& temp)
|
||||
{
|
||||
auto temp(std::make_shared<Member>(code, "", id, children));
|
||||
|
||||
auto tempdesc = std::make_shared<std::vector<FieldDesc>>();
|
||||
Member::Helper::build_tree(*tempdesc, *temp);
|
||||
|
||||
@@ -278,7 +272,33 @@ TypeDef::TypeDef(const Value& val)
|
||||
|
||||
TypeDef::~TypeDef() {}
|
||||
|
||||
void Member::Helper::append_tree(Member& node, const Member& adopt)
|
||||
Member TypeDef::as(const std::string& name) const
|
||||
{
|
||||
if(!top)
|
||||
throw std::logic_error("Can't append empty TypeDef");
|
||||
|
||||
Member ret(*top);
|
||||
ret.name = name;
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::shared_ptr<Member> TypeDef::_append_start()
|
||||
{
|
||||
if(!top || (top->code!=TypeCode::Struct && top->code!=TypeCode::Union))
|
||||
throw std::logic_error("May only append to Struct or Union");
|
||||
|
||||
std::shared_ptr<Member> edit;
|
||||
if(top.use_count()==1u) {
|
||||
edit = std::const_pointer_cast<Member>(top);
|
||||
top.reset(); // so we don't leave partial tree on error.
|
||||
} else {
|
||||
edit = std::make_shared<Member>(*top); // copy
|
||||
}
|
||||
|
||||
return edit;
|
||||
}
|
||||
|
||||
void TypeDef::_append(Member& node, const Member& adopt)
|
||||
{
|
||||
for(auto& child : node.children) {
|
||||
if(child.name==adopt.name) {
|
||||
@@ -293,7 +313,7 @@ void Member::Helper::append_tree(Member& node, const Member& adopt)
|
||||
child.id = adopt.id;
|
||||
|
||||
for(auto& grandchild : adopt.children) {
|
||||
append_tree(child, grandchild);
|
||||
_append(child, grandchild);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -303,23 +323,8 @@ void Member::Helper::append_tree(Member& node, const Member& adopt)
|
||||
node.children.push_back(adopt);
|
||||
}
|
||||
|
||||
TypeDef& TypeDef::operator+=(std::initializer_list<Member> children)
|
||||
void TypeDef::_append_finish(std::shared_ptr<Member>&& edit)
|
||||
{
|
||||
if(!top || (top->code!=TypeCode::Struct && top->code!=TypeCode::Union))
|
||||
throw std::logic_error("May only append to Struct or Union");
|
||||
|
||||
std::shared_ptr<Member> edit;
|
||||
if(top.use_count()==1u) {
|
||||
edit = std::const_pointer_cast<Member>(top);
|
||||
top.reset(); // so we don't leave partial tree on error.
|
||||
} else {
|
||||
edit = std::make_shared<Member>(*top); // copy
|
||||
}
|
||||
|
||||
for(auto& child : children) {
|
||||
Member::Helper::append_tree(*edit, child);
|
||||
}
|
||||
|
||||
auto temp = std::make_shared<std::vector<FieldDesc>>();
|
||||
Member::Helper::build_tree(*temp, *edit);
|
||||
|
||||
@@ -327,8 +332,6 @@ TypeDef& TypeDef::operator+=(std::initializer_list<Member> children)
|
||||
|
||||
top = std::move(edit);
|
||||
desc = std::move(type);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Value TypeDef::create() const
|
||||
|
||||
Reference in New Issue
Block a user