From 3b67c35afe30b6212f486af871f4faad940cbc6a Mon Sep 17 00:00:00 2001 From: Alexander Sherikov Date: Thu, 20 Jun 2024 23:56:19 +0400 Subject: [PATCH] + serialization::NodeStackBase --- extra_visitors/graphviz/src/writer.cpp | 81 ++++++++------- extra_visitors/msgpack/src/reader.cpp | 22 ++--- extra_visitors/msgpack/src/reader_compact.cpp | 27 +++-- .../ariles2/visitors/namevalue/writer.h | 64 ++++++------ extra_visitors/octave/src/writer.cpp | 98 +++++++++---------- extra_visitors/pugixml/src/reader.cpp | 33 +++---- extra_visitors/pugixml/src/writer.cpp | 24 ++--- extra_visitors/rapidjson/src/common.h | 8 +- extra_visitors/rapidjson/src/reader.cpp | 17 ++-- extra_visitors/rapidjson/src/writer.cpp | 13 ++- extra_visitors/ros2param/src/reader.cpp | 68 ++++--------- extra_visitors/ros2param/src/writer.cpp | 56 ++++------- extra_visitors/rosparam/src/common.h | 5 +- extra_visitors/rosparam/src/reader.cpp | 21 ++-- extra_visitors/rosparam/src/writer.cpp | 17 ++-- extra_visitors/yaml_cpp/src/reader.cpp | 26 +++-- include/ariles2/internal/helpers.h | 3 - include/ariles2/visitors/serialization.h | 72 +++++++++++++- qa/scspell.dict | 3 + 19 files changed, 320 insertions(+), 338 deletions(-) diff --git a/extra_visitors/graphviz/src/writer.cpp b/extra_visitors/graphviz/src/writer.cpp index e81c51bc..14322701 100644 --- a/extra_visitors/graphviz/src/writer.cpp +++ b/extra_visitors/graphviz/src/writer.cpp @@ -71,10 +71,9 @@ namespace ariles2 { namespace impl { - class ARILES2_VISIBILITY_ATTRIBUTE Visitor + class ARILES2_VISIBILITY_ATTRIBUTE Visitor : public serialization::NodeStackBase { public: - std::vector node_stack_; /// output file stream std::ofstream config_ofs_; @@ -84,6 +83,8 @@ namespace ariles2 std::set all_ids_; const Parameters *parameters_; + const std::string separator_ = "_"; + public: explicit Visitor(const std::string &file_name) @@ -114,9 +115,9 @@ namespace ariles2 ARILES2_ASSERT(0 < stack_size, "Internal error: stack must contain at least 2 entries."); // node - node_stack_.back().actual_id_ = node_options.id_; + back().actual_id_ = node_options.id_; - if (all_ids_.insert(node_stack_.back().actual_id_).second) + if (all_ids_.insert(back().actual_id_).second) { *output_stream_ << node_options.id_; *output_stream_ << "["; @@ -137,7 +138,7 @@ namespace ariles2 *output_stream_ // << node_stack_[stack_size - 2].actual_id_ // << "->" // - << node_stack_.back().actual_id_ << ";\n"; + << back().actual_id_ << ";\n"; } } }; @@ -175,16 +176,16 @@ namespace ariles2 impl_->parameters_ = ¶meters; if (name.empty()) { - impl_->node_stack_.emplace_back("ariles"); + impl_->emplace("ariles"); } else { - impl_->node_stack_.emplace_back(name); + impl_->emplace(name); } - *impl_->output_stream_ // - << "digraph graph_" << impl_->node_stack_.back().node_ // - << " {\n" // - << parameters.graph_options_; // + *impl_->output_stream_ // + << "digraph graph_" << impl_->back().node_ // + << " {\n" // + << parameters.graph_options_; // } @@ -196,22 +197,20 @@ namespace ariles2 std::string Visitor::getDefaultNodeId() const { - if (impl_->node_stack_.back().isArray()) + if (impl_->back().isArray()) { - return (impl_->node_stack_.back().node_ + "_" - + boost::lexical_cast(impl_->node_stack_.back().index_)); + return (impl_->back().node_ + "_" + boost::lexical_cast(impl_->back().index_)); } - return (impl_->node_stack_.back().node_); + return (impl_->back().node_); } std::string Visitor::getDefaultNodeLabel() const { - if (impl_->node_stack_.back().isArray()) + if (impl_->back().isArray()) { - return (impl_->node_stack_.back().label_ + "_" - + boost::lexical_cast(impl_->node_stack_.back().index_)); + return (impl_->back().label_ + "_" + boost::lexical_cast(impl_->back().index_)); } - return (impl_->node_stack_.back().label_); + return (impl_->back().label_); } void Visitor::startMap(const Parameters ¶meters, const Parameters::NodeOptions &node_options) @@ -238,32 +237,33 @@ namespace ariles2 void Visitor::startMapEntry(const std::string &name) { ARILES2_TRACE_FUNCTION; - if (impl_->node_stack_.back().isArray()) + if (impl_->back().isArray()) { - std::string node = impl_->node_stack_.back().node_; - node += "_"; - node += boost::lexical_cast(impl_->node_stack_.back().index_); - node += "_"; - node += name; - impl_->node_stack_.emplace_back(node, name); + impl_->emplace( + impl_->concatWithNode( + impl_->separator_, + boost::lexical_cast(impl_->back().index_), + impl_->separator_, + name), + name); } else { - impl_->node_stack_.emplace_back(impl_->node_stack_.back().node_ + "_" + name, name); + impl_->emplace(impl_->concatWithNode(impl_->separator_, name), name); } } void Visitor::endMapEntry() { ARILES2_TRACE_FUNCTION; - impl_->node_stack_.pop_back(); + impl_->pop(); } void Visitor::startArray(const std::size_t size, const bool compact) { ARILES2_TRACE_FUNCTION; - ARILES2_ASSERT(not impl_->node_stack_.empty(), "Internal error: empty stack."); + ARILES2_ASSERT(not impl_->empty(), "Internal error: empty stack."); if (size > 0 || not compact) { @@ -271,33 +271,30 @@ namespace ariles2 impl_->parameters_->getDefaultNodeOptions(getDefaultNodeId(), getDefaultNodeLabel())); } - if (impl_->node_stack_.back().isArray()) + if (impl_->back().isArray()) { - std::string node = impl_->node_stack_.back().node_; - std::string label = impl_->node_stack_.back().label_; - node += "_"; - node += boost::lexical_cast(impl_->node_stack_.back().index_); - label += "_"; - label += boost::lexical_cast(impl_->node_stack_.back().index_); - impl_->node_stack_.emplace_back(node, label, 0, size); + const std::string index = boost::lexical_cast(impl_->back().index_); + impl_->emplace( + impl_->concatWithNode(impl_->separator_, index), + impl_->concatenate(impl_->back().label_, impl_->separator_, index), + 0, + size); } else { - impl_->node_stack_.emplace_back( - impl_->node_stack_.back().node_, impl_->node_stack_.back().label_, 0, size); + impl_->emplace(impl_->back().node_, impl_->back().label_, 0, size); } } void Visitor::endArrayElement() { - ARILES2_ASSERT(impl_->node_stack_.back().isArray(), "Internal error: array expected."); - ++impl_->node_stack_.back().index_; + impl_->shiftArray(); } void Visitor::endArray() { ARILES2_TRACE_FUNCTION; - impl_->node_stack_.pop_back(); + impl_->pop(); } diff --git a/extra_visitors/msgpack/src/reader.cpp b/extra_visitors/msgpack/src/reader.cpp index c20b3c03..f3915738 100644 --- a/extra_visitors/msgpack/src/reader.cpp +++ b/extra_visitors/msgpack/src/reader.cpp @@ -31,16 +31,13 @@ namespace ariles2 { namespace impl { - class ARILES2_VISIBILITY_ATTRIBUTE Reader + class ARILES2_VISIBILITY_ATTRIBUTE Reader : public serialization::NodeStackBase { public: std::string buffer_; std::vector> handles_; - /// Stack of nodes. - std::vector node_stack_; - std::size_t nameless_counter_; @@ -138,7 +135,7 @@ namespace ariles2 { ARILES2_TRACE_FUNCTION; ARILES2_TRACE_VALUE(child_name); - if (impl_->node_stack_.empty()) + if (impl_->empty()) { for (std::size_t i = 0; i < impl_->handles_.size(); ++i) { @@ -148,7 +145,7 @@ namespace ariles2 { if (::msgpack::type::MAP == impl_->handles_[i]->get().via.map.ptr[0].val.type) { - impl_->node_stack_.emplace_back(&(impl_->handles_[i]->get().via.map.ptr[0].val)); + impl_->emplace(&(impl_->handles_[i]->get().via.map.ptr[0].val)); return (true); } } @@ -163,7 +160,7 @@ namespace ariles2 { if (child_name == impl_->getRawNode().via.map.ptr[i].key.as()) { - impl_->node_stack_.emplace_back(&(impl_->getRawNode().via.map.ptr[i].val)); + impl_->emplace(&(impl_->getRawNode().via.map.ptr[i].val)); return (true); } } @@ -177,7 +174,7 @@ namespace ariles2 void Reader::endMapEntry() { ARILES2_TRACE_FUNCTION; - impl_->node_stack_.pop_back(); + impl_->pop(); } @@ -185,7 +182,7 @@ namespace ariles2 { ARILES2_TRACE_FUNCTION; const std::size_t size = impl_->getRawNode().via.array.size; - impl_->node_stack_.emplace_back(0, size); + impl_->emplace(0, size); return (size); } @@ -194,14 +191,14 @@ namespace ariles2 void Reader::endArray() { ARILES2_TRACE_FUNCTION; - impl_->node_stack_.pop_back(); + impl_->pop(); } void Reader::startArrayElement() { ARILES2_ASSERT( - impl_->node_stack_.back().index_ < impl_->node_stack_.back().size_, + impl_->back().index_ < impl_->back().size_, "Internal error: array has more elements than expected."); } @@ -209,8 +206,7 @@ namespace ariles2 void Reader::endArrayElement() { ARILES2_TRACE_FUNCTION; - ARILES2_ASSERT(impl_->node_stack_.back().isArray(), "Internal error: expected array."); - ++impl_->node_stack_.back().index_; + impl_->shiftArray(); } diff --git a/extra_visitors/msgpack/src/reader_compact.cpp b/extra_visitors/msgpack/src/reader_compact.cpp index 01d73574..52fd4be5 100644 --- a/extra_visitors/msgpack/src/reader_compact.cpp +++ b/extra_visitors/msgpack/src/reader_compact.cpp @@ -33,16 +33,13 @@ namespace ariles2 { namespace impl { - class ARILES2_VISIBILITY_ATTRIBUTE Reader + class ARILES2_VISIBILITY_ATTRIBUTE Reader : public serialization::NodeStackBase { public: std::string buffer_; ::msgpack::object_handle handle_; - /// Stack of nodes. - std::vector node_stack_; - public: /** @@ -59,7 +56,7 @@ namespace ariles2 try { unpack(handle_, buffer_.data(), buffer_.size(), nullptr); - node_stack_.emplace_back(&handle_.get()); + emplace(&handle_.get()); } catch (const std::exception &e) { @@ -118,12 +115,12 @@ namespace ariles2 { const std::size_t size = impl_->getRawNode().via.array.size; checkSize(limit_type, size, min, max); - impl_->node_stack_.emplace_back(0, size); + impl_->emplace(0, size); } bool Reader::startMapEntry(const std::string &) { - if (impl_->node_stack_.back().isArray()) + if (impl_->back().isArray()) { startArrayElement(); } @@ -132,7 +129,7 @@ namespace ariles2 void Reader::endMapEntry() { - if (impl_->node_stack_.back().isArray()) + if (impl_->back().isArray()) { endArrayElement(); } @@ -141,16 +138,15 @@ namespace ariles2 void Reader::endMap() { ARILES2_ASSERT( - impl_->node_stack_.back().isCompleted(), - "Some entries were not parsed, which is not allowed by this visitor."); - impl_->node_stack_.pop_back(); + impl_->back().isCompleted(), "Some entries were not parsed, which is not allowed by this visitor."); + impl_->pop(); } std::size_t Reader::startArray() { const std::size_t size = impl_->getRawNode().via.array.size; - impl_->node_stack_.emplace_back(0, size); + impl_->emplace(0, size); return (size); } @@ -158,22 +154,21 @@ namespace ariles2 void Reader::endArray() { - impl_->node_stack_.pop_back(); + impl_->pop(); } void Reader::startArrayElement() { ARILES2_ASSERT( - impl_->node_stack_.back().index_ < impl_->node_stack_.back().size_, + impl_->back().index_ < impl_->back().size_, "Internal error: array has more elements than expected."); } void Reader::endArrayElement() { - ARILES2_ASSERT(impl_->node_stack_.back().isArray(), "Internal error: expected array."); - ++impl_->node_stack_.back().index_; + impl_->shiftArray(); } diff --git a/extra_visitors/namevalue/ariles2/visitors/namevalue/writer.h b/extra_visitors/namevalue/ariles2/visitors/namevalue/writer.h index 2c0963c8..d4f76ccf 100644 --- a/extra_visitors/namevalue/ariles2/visitors/namevalue/writer.h +++ b/extra_visitors/namevalue/ariles2/visitors/namevalue/writer.h @@ -49,20 +49,21 @@ namespace ariles2 * @brief Configuration writer class */ template - class ARILES2_VISIBILITY_ATTRIBUTE GenericWriter : public ariles2::write::Visitor + class ARILES2_VISIBILITY_ATTRIBUTE GenericWriter + : public ariles2::write::Visitor, + public serialization::NodeStackBase> { protected: - using NodeWrapper = serialization::Node; - - - protected: - std::vector node_stack_; std::size_t reserve_; std::vector buffer_name_value_pairs_; bool initialize_structure_; + const std::string separator_ = "."; + const std::string bracket_left_ = "{"; + const std::string bracket_right_ = "}"; + public: std::vector *name_value_pairs_; @@ -144,30 +145,25 @@ namespace ariles2 { if (initialize_structure_) { - if (0 == node_stack_.size()) + if (empty()) { - node_stack_.emplace_back(map_name); + emplace(map_name); } else { - std::string node; - if (node_stack_.back().isArray()) + if (back().isArray()) { - node.reserve(node_stack_.back().node_.size() + map_name.size() + num_chars_for_index_reserve + 3); - - node = node_stack_.back().node_; - node += "{"; - node += boost::lexical_cast(node_stack_.back().index_); - node += "}."; + concatWithNodeAndEmplace( + bracket_left_, + boost::lexical_cast(back().index_), + bracket_right_, + separator_, + map_name); } else { - node.reserve(node_stack_.back().node_.size() + map_name.size() + 1); - node = node_stack_.back().node_; - node += "."; + concatWithNodeAndEmplace(separator_, map_name); } - node += map_name; - node_stack_.emplace_back(std::move(node)); } } } @@ -176,7 +172,7 @@ namespace ariles2 { if (initialize_structure_) { - node_stack_.pop_back(); + pop(); } } @@ -195,18 +191,15 @@ namespace ariles2 if (initialize_structure_) { expandReserve(size); - if (node_stack_.back().isArray()) + if (back().isArray()) { - std::string node; - node.reserve(node_stack_.back().node_.size() + 15); - node = node_stack_.back().node_; - node += "_"; - node += boost::lexical_cast(node_stack_.back().index_); - node_stack_.emplace_back(std::move(node), 0, size); + emplace(concatWithNode(std::string("_"), boost::lexical_cast(back().index_)), + 0, + size); } else { - node_stack_.emplace_back(node_stack_.back().node_, 0, size); + emplace(back().node_, 0, size); } } } @@ -215,8 +208,7 @@ namespace ariles2 { if (initialize_structure_) { - ARILES2_ASSERT(node_stack_.back().isArray(), "Internal error: array expected."); - ++node_stack_.back().index_; + shiftArray(); } } @@ -224,7 +216,7 @@ namespace ariles2 { if (initialize_structure_) { - node_stack_.pop_back(); + pop(); } } @@ -235,12 +227,12 @@ namespace ariles2 expand(); \ if (initialize_structure_) \ { \ - NameValuePairHandler::name((*name_value_pairs_)[index_]) = node_stack_.back().node_; \ - if (node_stack_.back().isArray()) \ + NameValuePairHandler::name((*name_value_pairs_)[index_]) = back().node_; \ + if (back().isArray()) \ { \ NameValuePairHandler::name((*name_value_pairs_)[index_]) += "_"; \ NameValuePairHandler::name((*name_value_pairs_)[index_]) += \ - boost::lexical_cast(node_stack_.back().index_); \ + boost::lexical_cast(back().index_); \ } \ } \ NameValuePairHandler::value((*name_value_pairs_)[index_]) = element; \ diff --git a/extra_visitors/octave/src/writer.cpp b/extra_visitors/octave/src/writer.cpp index 0982bfdb..7ae79726 100644 --- a/extra_visitors/octave/src/writer.cpp +++ b/extra_visitors/octave/src/writer.cpp @@ -31,17 +31,19 @@ namespace ariles2 { namespace impl { - class ARILES2_VISIBILITY_ATTRIBUTE Writer + class ARILES2_VISIBILITY_ATTRIBUTE Writer : public serialization::NodeStackBase { public: - std::vector node_stack_; - /// output file stream std::ofstream config_ofs_; /// output stream std::ostream *output_stream_; + const std::string separator_ = "."; + const std::string bracket_left_ = "{"; + const std::string bracket_right_ = "}"; + protected: /** @@ -70,16 +72,16 @@ namespace ariles2 template void writeComplex(const std::complex &element) { - if (node_stack_.back().isMatrix()) + if (back().isMatrix()) { *output_stream_ << element.real() << " + " << element.imag() << "i"; } else { - *output_stream_ << node_stack_.back().node_; - if (node_stack_.back().isArray()) + *output_stream_ << back().node_; + if (back().isArray()) { - *output_stream_ << "{" << node_stack_.back().index_ + 1 << "}"; + *output_stream_ << "{" << back().index_ + 1 << "}"; } *output_stream_ << " = " << element.real() << " + " << element.imag() << "i" << ";\n"; @@ -115,73 +117,67 @@ namespace ariles2 void Writer::startMapEntry(const std::string &map_name) { - if (impl_->node_stack_.empty()) + if (impl_->empty()) { - impl_->node_stack_.emplace_back(map_name); + impl_->emplace(map_name); } else { - std::string node; - if (impl_->node_stack_.back().isArray()) + if (impl_->back().isArray()) { - node.reserve(impl_->node_stack_.back().node_.size() + map_name.size() + num_chars_for_index_reserve + 3); - - node = impl_->node_stack_.back().node_; - node += "{"; - node += boost::lexical_cast(impl_->node_stack_.back().index_ + 1); - node += "}."; + impl_->concatWithNodeAndEmplace( + impl_->bracket_left_, + boost::lexical_cast(impl_->back().index_ + 1), + impl_->bracket_right_, + impl_->separator_, + map_name); } else { - node.reserve(impl_->node_stack_.back().node_.size() + map_name.size() + 1); - node = impl_->node_stack_.back().node_; - node += "."; + impl_->concatWithNodeAndEmplace(impl_->separator_, map_name); } - node += map_name; - impl_->node_stack_.emplace_back(std::move(node)); } } void Writer::endMapEntry() { - impl_->node_stack_.pop_back(); + impl_->pop(); } void Writer::startArray(const std::size_t size, const bool /*compact*/) { - if (impl_->node_stack_.back().isArray()) + if (impl_->back().isArray()) { - std::string node; - node.reserve(impl_->node_stack_.back().node_.size() + num_chars_for_index_reserve + 2); - node = impl_->node_stack_.back().node_; - node += "{"; - node += boost::lexical_cast(impl_->node_stack_.back().index_ + 1); - node += "}"; - impl_->node_stack_.emplace_back(std::move(node), 0, size); + impl_->emplace( + impl_->concatWithNode( + impl_->bracket_left_, + boost::lexical_cast(impl_->back().index_ + 1), + impl_->bracket_right_), + 0, + size); } else { - impl_->node_stack_.emplace_back(impl_->node_stack_.back().node_, 0, size); + impl_->emplace(impl_->back().node_, 0, size); } } void Writer::endArrayElement() { - ARILES2_ASSERT(impl_->node_stack_.back().isArray(), "Internal error: array expected."); - ++impl_->node_stack_.back().index_; + impl_->shiftArray(); } void Writer::endArray() { - impl_->node_stack_.pop_back(); + impl_->pop(); } void Writer::startVector(const std::size_t /*size*/) { - impl_->node_stack_.emplace_back(impl_->node_stack_.back().node_ + " = [", NodeWrapper::Type::MATRIX); - *impl_->output_stream_ << impl_->node_stack_.back().node_; + impl_->emplace(impl_->back().node_ + " = [", NodeWrapper::Type::MATRIX); + *impl_->output_stream_ << impl_->back().node_; } void Writer::startVectorElement() @@ -196,7 +192,7 @@ namespace ariles2 void Writer::endVector() { *impl_->output_stream_ << "];\n"; - impl_->node_stack_.pop_back(); + impl_->pop(); } @@ -206,18 +202,18 @@ namespace ariles2 const std::size_t /*rows*/, const Parameters & /*param*/) { - impl_->node_stack_.emplace_back(impl_->node_stack_.back().node_ + " = [...\n", NodeWrapper::Type::MATRIX); - *impl_->output_stream_ << impl_->node_stack_.back().node_; + impl_->emplace(impl_->back().node_ + " = [...\n", NodeWrapper::Type::MATRIX); + *impl_->output_stream_ << impl_->back().node_; } void Writer::startMatrixRow(const std::size_t /*cols*/, const Parameters & /*param*/) { - impl_->node_stack_.back().index_ = 0; + impl_->back().index_ = 0; } void Writer::startMatrixElement() { - if (0 != impl_->node_stack_.back().index_) + if (0 != impl_->back().index_) { *impl_->output_stream_ << ", "; } @@ -225,7 +221,7 @@ namespace ariles2 void Writer::endMatrixElement() { - ++impl_->node_stack_.back().index_; + ++impl_->back().index_; } void Writer::endMatrixRow(const Parameters & /*param*/) @@ -236,23 +232,23 @@ namespace ariles2 void Writer::endMatrix(const bool /*dynamic*/, const Parameters & /*param*/) { *impl_->output_stream_ << "];\n"; - impl_->node_stack_.pop_back(); + impl_->pop(); } #define ARILES2_BASIC_TYPE(type) \ void Writer::writeElement(const type &element, const Parameters &) \ { \ - if (impl_->node_stack_.back().isMatrix()) \ + if (impl_->back().isMatrix()) \ { \ *impl_->output_stream_ << element; \ } \ else \ { \ - *impl_->output_stream_ << impl_->node_stack_.back().node_; \ - if (impl_->node_stack_.back().isArray()) \ + *impl_->output_stream_ << impl_->back().node_; \ + if (impl_->back().isArray()) \ { \ - *impl_->output_stream_ << "{" << impl_->node_stack_.back().index_ + 1 << "}"; \ + *impl_->output_stream_ << "{" << impl_->back().index_ + 1 << "}"; \ } \ *impl_->output_stream_ << " = " << element << ";\n"; \ } \ @@ -265,10 +261,10 @@ namespace ariles2 void Writer::writeElement(const std::string &element, const Parameters &) { - *impl_->output_stream_ << impl_->node_stack_.back().node_; - if (impl_->node_stack_.back().isArray()) + *impl_->output_stream_ << impl_->back().node_; + if (impl_->back().isArray()) { - *impl_->output_stream_ << "{" << impl_->node_stack_.back().index_ + 1 << "}"; + *impl_->output_stream_ << "{" << impl_->back().index_ + 1 << "}"; } *impl_->output_stream_ << " = '" << element << "';\n"; } diff --git a/extra_visitors/pugixml/src/reader.cpp b/extra_visitors/pugixml/src/reader.cpp index a18d52c6..83d8a605 100644 --- a/extra_visitors/pugixml/src/reader.cpp +++ b/extra_visitors/pugixml/src/reader.cpp @@ -17,13 +17,11 @@ namespace ariles2 { namespace impl { - class ARILES2_VISIBILITY_ATTRIBUTE Reader + class ARILES2_VISIBILITY_ATTRIBUTE Reader : public serialization::NodeStackBase { public: pugi::xml_document document_; - std::vector node_stack_; - public: /** @@ -33,7 +31,7 @@ namespace ariles2 */ pugi::xml_node &getRawNode() { - return (node_stack_.back().node_); + return (back().node_); } }; } // namespace impl @@ -71,7 +69,7 @@ namespace ariles2 if (nullptr != child) { - impl_->node_stack_.emplace_back(child); + impl_->emplace(child); return (true); } @@ -80,7 +78,7 @@ namespace ariles2 { const pugi::xml_node new_child = impl_->getRawNode().append_child(child_name.c_str()); new_child.text() = attribute.value(); - impl_->node_stack_.emplace_back(new_child); + impl_->emplace(new_child); return (true); } @@ -90,7 +88,7 @@ namespace ariles2 void Reader::endMapEntry() { - impl_->node_stack_.pop_back(); + impl_->pop(); } @@ -102,7 +100,7 @@ namespace ariles2 const pugi::xml_node child = impl_->getRawNode().first_child(); if (nullptr != child) { - impl_->node_stack_.emplace_back(child, NodeWrapper::Type::ITERATED_MAP); + impl_->emplace(child, NodeWrapper::Type::ITERATED_MAP); return (true); } return (false); @@ -130,7 +128,7 @@ namespace ariles2 void Reader::endIteratedMap() { ARILES2_ASSERT(!impl_->getRawNode(), "End of iterated map has not been reached."); - impl_->node_stack_.pop_back(); + impl_->pop(); } @@ -138,13 +136,14 @@ namespace ariles2 { std::size_t size = 0; const pugi::xml_node node = impl_->getRawNode(); - for (pugi::xml_node child = node.child("item"); nullptr != child; child = child.next_sibling("item"), ++size) + for (pugi::xml_node child = node.child("item"); nullptr != child; + child = child.next_sibling("item"), ++size) { } if (size > 0) { - impl_->node_stack_.emplace_back(node.child("item"), 0, size); + impl_->emplace(node.child("item"), 0, size); } else { @@ -155,7 +154,7 @@ namespace ariles2 child = child.next_sibling(child.name()), ++size) { } - impl_->node_stack_.emplace_back(impl_->getRawNode(), 0, size); + impl_->emplace(impl_->getRawNode(), 0, size); } return (size); @@ -165,22 +164,22 @@ namespace ariles2 void Reader::startArrayElement() { ARILES2_ASSERT( - impl_->node_stack_.back().index_ < impl_->node_stack_.back().size_, + impl_->back().index_ < impl_->back().size_, "Internal error: array has more elements than expected."); } void Reader::endArrayElement() { - ARILES2_ASSERT(impl_->node_stack_.back().isArray(), "Internal error: expected array."); - impl_->node_stack_.back().node_ = impl_->getRawNode().next_sibling(impl_->getRawNode().name()); - ++impl_->node_stack_.back().index_; + ARILES2_ASSERT(impl_->back().isArray(), "Internal error: expected array."); + impl_->back().node_ = impl_->getRawNode().next_sibling(impl_->getRawNode().name()); + ++impl_->back().index_; } void Reader::endArray() { - impl_->node_stack_.pop_back(); + impl_->pop(); } diff --git a/extra_visitors/pugixml/src/writer.cpp b/extra_visitors/pugixml/src/writer.cpp index 9b6c46a4..e9fc2882 100644 --- a/extra_visitors/pugixml/src/writer.cpp +++ b/extra_visitors/pugixml/src/writer.cpp @@ -16,14 +16,11 @@ namespace ariles2 { namespace impl { - class ARILES2_VISIBILITY_ATTRIBUTE Writer + class ARILES2_VISIBILITY_ATTRIBUTE Writer : public serialization::NodeStackBase { public: pugi::xml_document document_; - std::vector node_stack_; - - /// output file stream std::ofstream config_ofs_; @@ -55,7 +52,7 @@ namespace ariles2 */ pugi::xml_node &getRawNode() { - return (node_stack_.back().node_); + return (back().node_); } }; } // namespace impl @@ -89,38 +86,37 @@ namespace ariles2 void Writer::startMapEntry(const std::string &map_name) { - impl_->node_stack_.emplace_back(impl_->getRawNode().append_child(map_name.c_str())); + impl_->emplace(impl_->getRawNode().append_child(map_name.c_str())); } void Writer::endMapEntry() { - impl_->node_stack_.pop_back(); + impl_->pop(); } void Writer::startArray(const std::size_t size, const bool /*compact*/) { - impl_->node_stack_.emplace_back(impl_->getRawNode(), 0, size); + impl_->emplace(impl_->getRawNode(), 0, size); } void Writer::startArrayElement() { ARILES2_ASSERT( - impl_->node_stack_.back().index_ < impl_->node_stack_.back().size_, + impl_->back().index_ < impl_->back().size_, "Internal error: array has more elements than expected."); - impl_->node_stack_.emplace_back(impl_->getRawNode().append_child("item")); + impl_->emplace(impl_->getRawNode().append_child("item")); } void Writer::endArrayElement() { - impl_->node_stack_.pop_back(); - ARILES2_ASSERT(impl_->node_stack_.back().isArray(), "Internal error: expected array."); - ++impl_->node_stack_.back().index_; + impl_->pop(); + impl_->shiftArray(); } void Writer::endArray() { - impl_->node_stack_.pop_back(); + impl_->pop(); } diff --git a/extra_visitors/rapidjson/src/common.h b/extra_visitors/rapidjson/src/common.h index 810f8e89..93263fc9 100644 --- a/extra_visitors/rapidjson/src/common.h +++ b/extra_visitors/rapidjson/src/common.h @@ -30,19 +30,15 @@ namespace ariles2 namespace ns_rapidjson { template - class ARILES2_LIB_LOCAL ImplBase + class ARILES2_LIB_LOCAL ImplBase : public serialization::NodeStackBase> { public: - using NodeWrapper = serialization::Node; - + using serialization::NodeStackBase>::node_stack_; public: /// instance of the parser ::rapidjson::Document document_; - /// Stack of nodes. - std::vector node_stack_; - public: /** diff --git a/extra_visitors/rapidjson/src/reader.cpp b/extra_visitors/rapidjson/src/reader.cpp index 4ac86f9c..e4613565 100644 --- a/extra_visitors/rapidjson/src/reader.cpp +++ b/extra_visitors/rapidjson/src/reader.cpp @@ -79,13 +79,13 @@ namespace ariles2 { return (false); } - impl_->node_stack_.emplace_back(&(child->value)); + impl_->emplace(&(child->value)); return (true); } void Reader::endMapEntry() { - impl_->node_stack_.pop_back(); + impl_->pop(); } @@ -112,7 +112,7 @@ namespace ariles2 { if (impl_->iterator_stack_.back() != impl_->getRawNode().MemberEnd()) { - impl_->node_stack_.emplace_back(&(impl_->iterator_stack_.back()->value)); + impl_->emplace(&(impl_->iterator_stack_.back()->value)); entry_name = impl_->iterator_stack_.back()->name.GetString(); return (true); } @@ -122,7 +122,7 @@ namespace ariles2 void Reader::endIteratedMapElement() { ++impl_->iterator_stack_.back(); - impl_->node_stack_.pop_back(); + impl_->pop(); } void Reader::endIteratedMap() @@ -139,7 +139,7 @@ namespace ariles2 ARILES2_ASSERT(impl_->getRawNode().IsArray(), "Internal error: expected array."); std::size_t size = impl_->getRawNode().Size(); - impl_->node_stack_.emplace_back(0, size); + impl_->emplace(0, size); return (size); } @@ -148,21 +148,20 @@ namespace ariles2 void Reader::startArrayElement() { ARILES2_ASSERT( - impl_->node_stack_.back().index_ < impl_->node_stack_.back().size_, + impl_->back().index_ < impl_->back().size_, "Internal error: array has more elements than expected."); } void Reader::endArrayElement() { - ARILES2_ASSERT(impl_->node_stack_.back().isArray(), "Internal error: expected array."); - ++impl_->node_stack_.back().index_; + impl_->shiftArray(); } void Reader::endArray() { - impl_->node_stack_.pop_back(); + impl_->pop(); } diff --git a/extra_visitors/rapidjson/src/writer.cpp b/extra_visitors/rapidjson/src/writer.cpp index 3dba2934..046add5a 100644 --- a/extra_visitors/rapidjson/src/writer.cpp +++ b/extra_visitors/rapidjson/src/writer.cpp @@ -95,12 +95,12 @@ namespace ariles2 // hack, we assume that the last added // child is the last in the list const ::rapidjson::Value::MemberIterator child = --(impl_->getRawNode().MemberEnd()); - impl_->node_stack_.emplace_back(&(child->value)); + impl_->emplace(&(child->value)); } void Writer::endMapEntry() { - impl_->node_stack_.pop_back(); + impl_->pop(); } @@ -114,28 +114,27 @@ namespace ariles2 ::rapidjson::Value value; impl_->getRawNode().PushBack(value, impl_->document_.GetAllocator()); } - impl_->node_stack_.emplace_back(0, size); + impl_->emplace(0, size); } void Writer::startArrayElement() { ARILES2_TRACE_FUNCTION; ARILES2_ASSERT( - impl_->node_stack_.back().index_ < impl_->node_stack_.back().size_, + impl_->back().index_ < impl_->back().size_, "Internal error: array has more elements than expected."); } void Writer::endArrayElement() { ARILES2_TRACE_FUNCTION; - ARILES2_ASSERT(impl_->node_stack_.back().isArray(), "Internal error: expected array."); - ++impl_->node_stack_.back().index_; + impl_->shiftArray(); } void Writer::endArray() { ARILES2_TRACE_FUNCTION; - impl_->node_stack_.pop_back(); + impl_->pop(); } diff --git a/extra_visitors/ros2param/src/reader.cpp b/extra_visitors/ros2param/src/reader.cpp index cee320b2..d33ed416 100644 --- a/extra_visitors/ros2param/src/reader.cpp +++ b/extra_visitors/ros2param/src/reader.cpp @@ -151,17 +151,16 @@ namespace ariles2 namespace impl { - class ARILES2_VISIBILITY_ATTRIBUTE Reader + class ARILES2_VISIBILITY_ATTRIBUTE Reader : public serialization::NodeStackBase { public: - /// Stack of nodes. - std::vector node_stack_; - // https://docs.ros2.org/latest/api/rclcpp/classrclcpp_1_1Node.html const rclcpp::Node *nh_; std::vector parameter_names_; + const std::string separator_ = "."; + public: explicit Reader(const ::rclcpp::Node *nh) @@ -169,15 +168,6 @@ namespace ariles2 nh_ = nh; } - ReaderNodeWrapper &back() - { - return (node_stack_.back()); - } - - [[nodiscard]] const ReaderNodeWrapper &back() const - { - return (node_stack_.back()); - } bool getParameter(rclcpp::Parameter ¶meter) const { @@ -202,7 +192,7 @@ namespace ariles2 void reset() { - node_stack_.clear(); + clear(); rcl_interfaces::msg::ListParametersResult list_msg; parameter_names_ = std::move(nh_->list_parameters({}, std::numeric_limits::max()).names); @@ -240,7 +230,7 @@ namespace ariles2 { std::size_t substr_start = 0; - if (not node_stack_.empty()) + if (not empty()) { substr_start = back().node_.size() + 1; // + 1 for dot } @@ -311,20 +301,15 @@ namespace ariles2 bool Reader::startMapEntry(const std::string &child_name) { ARILES2_TRACE_FUNCTION; - if (impl_->node_stack_.empty()) + if (impl_->empty()) { - impl_->node_stack_.emplace_back(child_name); + impl_->emplace(child_name); } else { ARILES2_ASSERT(not impl_->back().isBuiltinArray(), "Unexpected parent type (builtin array)."); - std::string node; - node.reserve(impl_->back().node_.size() + child_name.size() + 1); - node = impl_->back().node_; - node += "."; - node += child_name; - impl_->node_stack_.emplace_back(std::move(node)); + impl_->concatWithNodeAndEmplace(impl_->separator_, child_name); } return (impl_->hasParameterPrefix()); @@ -333,7 +318,7 @@ namespace ariles2 void Reader::endMapEntry() { ARILES2_TRACE_FUNCTION; - impl_->node_stack_.pop_back(); + impl_->pop(); } @@ -349,7 +334,7 @@ namespace ariles2 checkSize(limit_type, name_list.size(), min, max); - impl_->node_stack_.emplace_back(impl_->back().node_, std::move(name_list)); + impl_->emplace(impl_->back().node_, std::move(name_list)); return (true); } @@ -362,20 +347,14 @@ namespace ariles2 } entry_name = impl_->back().getChildName(); - - std::string node; - node.reserve(impl_->back().node_.size() + entry_name.size() + 1); - node = impl_->back().node_; - node += "."; - node += entry_name; - impl_->node_stack_.emplace_back(std::move(node)); + impl_->concatWithNodeAndEmplace(impl_->separator_, entry_name); return (true); } void Reader::endIteratedMapElement() { - impl_->node_stack_.pop_back(); + impl_->pop(); ++(impl_->back().index_); } @@ -383,7 +362,7 @@ namespace ariles2 { ARILES2_TRACE_FUNCTION; ARILES2_ASSERT(impl_->back().isCompleted(), "End of iterated map has not been reached."); - impl_->node_stack_.pop_back(); + impl_->pop(); } @@ -391,15 +370,15 @@ namespace ariles2 { ARILES2_TRACE_FUNCTION; - if (not impl_->node_stack_.empty() and impl_->isParameter()) + if (not impl_->empty() and impl_->isParameter()) { rclcpp::Parameter values; impl_->getParameter(values); - impl_->node_stack_.emplace_back(std::move(values)); + impl_->emplace(std::move(values)); } else { - impl_->node_stack_.emplace_back(impl_->back().node_, 0, impl_->listParameters().size()); + impl_->emplace(impl_->back().node_, 0, impl_->listParameters().size()); } return (impl_->back().size_); @@ -412,13 +391,7 @@ namespace ariles2 ARILES2_ASSERT(not impl_->back().isCompleted(), "Internal error: array has more elements than expected."); if (impl_->back().isNonBuiltinArray()) { - std::string node; - node.reserve(impl_->back().node_.size() + num_chars_for_index_reserve + 1); - node = impl_->back().node_; - node += "."; - node += boost::lexical_cast(impl_->back().index_); - - impl_->node_stack_.emplace_back(std::move(node)); + impl_->concatWithNodeAndEmplace(impl_->separator_, boost::lexical_cast(impl_->back().index_)); } } @@ -427,16 +400,15 @@ namespace ariles2 ARILES2_TRACE_FUNCTION; if (not impl_->back().isBuiltinArray()) { - impl_->node_stack_.pop_back(); + impl_->pop(); } - ARILES2_ASSERT(impl_->back().isArray(), "Internal error: expected array."); - ++(impl_->back().index_); + impl_->shiftArray(); } void Reader::endArray() { ARILES2_TRACE_FUNCTION; - impl_->node_stack_.pop_back(); + impl_->pop(); } diff --git a/extra_visitors/ros2param/src/writer.cpp b/extra_visitors/ros2param/src/writer.cpp index 1b9388cb..39c3e890 100644 --- a/extra_visitors/ros2param/src/writer.cpp +++ b/extra_visitors/ros2param/src/writer.cpp @@ -103,32 +103,22 @@ namespace ariles2 namespace impl { - class ARILES2_VISIBILITY_ATTRIBUTE Writer + class ARILES2_VISIBILITY_ATTRIBUTE Writer : public serialization::NodeStackBase { public: - /// Stack of nodes. - std::vector node_stack_; - // https://docs.ros2.org/latest/api/rclcpp/classrclcpp_1_1Node.html rclcpp::Node *nh_; std::vector parameters_; + const std::string separator_ = "."; + public: explicit Writer(::rclcpp::Node *nh) { nh_ = nh; } - WriterNodeWrapper &back() - { - return (node_stack_.back()); - } - - [[nodiscard]] const WriterNodeWrapper &back() const - { - return (node_stack_.back()); - } [[nodiscard]] bool publishParameters() const { @@ -187,35 +177,31 @@ namespace ariles2 { ARILES2_TRACE_FUNCTION; ARILES2_TRACE_VALUE(child_name); - if (impl_->node_stack_.empty()) + if (impl_->empty()) { - impl_->node_stack_.emplace_back(child_name); + impl_->emplace(child_name); } else { - std::string node; if (impl_->back().isArray()) { - node.reserve(impl_->back().node_.size() + child_name.size() + num_chars_for_index_reserve + 3); - node = impl_->back().node_; - node += "."; - node += boost::lexical_cast(impl_->back().index_); + impl_->concatWithNodeAndEmplace( + impl_->separator_, + boost::lexical_cast(impl_->back().index_), + impl_->separator_, + child_name); } else { - node.reserve(impl_->back().node_.size() + child_name.size() + 1); - node = impl_->back().node_; + impl_->concatWithNodeAndEmplace(impl_->separator_, child_name); } - node += "."; - node += child_name; - impl_->node_stack_.emplace_back(std::move(node)); } } void Writer::endMapEntry() { ARILES2_TRACE_FUNCTION; - impl_->node_stack_.pop_back(); + impl_->pop(); } @@ -224,16 +210,15 @@ namespace ariles2 ARILES2_TRACE_FUNCTION; if (impl_->back().isArray()) { - std::string node; - node.reserve(impl_->back().node_.size() + num_chars_for_index_reserve + 1); - node = impl_->back().node_; - node += "."; - node += boost::lexical_cast(impl_->back().index_); - impl_->node_stack_.emplace_back(node, /*index=*/0, size); + impl_->emplace( + impl_->concatWithNode( + impl_->separator_, boost::lexical_cast(impl_->back().index_)), + /*index=*/0, + size); } else { - impl_->node_stack_.emplace_back(impl_->back().node_, /*index=*/0, size); + impl_->emplace(impl_->back().node_, /*index=*/0, size); } } @@ -246,15 +231,14 @@ namespace ariles2 void Writer::endArrayElement() { ARILES2_TRACE_FUNCTION; - ARILES2_ASSERT(impl_->back().isArray(), "Internal error: expected array."); - ++impl_->back().index_; + impl_->shiftArray(); } void Writer::endArray() { ARILES2_TRACE_FUNCTION; impl_->setParameter(); - impl_->node_stack_.pop_back(); + impl_->pop(); } diff --git a/extra_visitors/rosparam/src/common.h b/extra_visitors/rosparam/src/common.h index bcfd4fcc..61c2a936 100644 --- a/extra_visitors/rosparam/src/common.h +++ b/extra_visitors/rosparam/src/common.h @@ -25,12 +25,9 @@ namespace ariles2 using NodeWrapper = serialization::Node; - class ARILES2_LIB_LOCAL ImplBase + class ARILES2_LIB_LOCAL ImplBase : public serialization::NodeStackBase { public: - /// Stack of nodes. - std::vector node_stack_; - std::string root_name_; XmlRpc::XmlRpcValue root_value_; diff --git a/extra_visitors/rosparam/src/reader.cpp b/extra_visitors/rosparam/src/reader.cpp index 80fc7b96..e0372b29 100644 --- a/extra_visitors/rosparam/src/reader.cpp +++ b/extra_visitors/rosparam/src/reader.cpp @@ -62,18 +62,18 @@ namespace ariles2 bool Reader::startMapEntry(const std::string &child_name) { - if (impl_->node_stack_.empty()) + if (impl_->empty()) { impl_->root_name_ = child_name; impl_->nh_.getParam(impl_->root_name_, impl_->root_value_); - impl_->node_stack_.emplace_back(&impl_->root_value_); + impl_->emplace(&impl_->root_value_); return (true); } XmlRpc::XmlRpcValue &node = impl_->getRawNode(); if ((XmlRpc::XmlRpcValue::TypeStruct == node.getType()) && (node.hasMember(child_name))) { - impl_->node_stack_.emplace_back(&(node[child_name])); + impl_->emplace(&(node[child_name])); return (true); } return (false); @@ -81,7 +81,7 @@ namespace ariles2 void Reader::endMapEntry() { - impl_->node_stack_.pop_back(); + impl_->pop(); } @@ -106,7 +106,7 @@ namespace ariles2 { if (impl_->iterator_stack_.back() != impl_->getRawNode().end()) { - impl_->node_stack_.emplace_back(&impl_->iterator_stack_.back()->second); + impl_->emplace(&impl_->iterator_stack_.back()->second); entry_name = impl_->iterator_stack_.back()->first; return (true); } @@ -116,7 +116,7 @@ namespace ariles2 void Reader::endIteratedMapElement() { ++impl_->iterator_stack_.back(); - impl_->node_stack_.pop_back(); + impl_->pop(); } void Reader::endIteratedMap() @@ -133,7 +133,7 @@ namespace ariles2 ARILES2_ASSERT(XmlRpc::XmlRpcValue::TypeArray == impl_->getRawNode().getType(), "Expected array."); std::size_t size = impl_->getRawNode().size(); - impl_->node_stack_.emplace_back(0, size); + impl_->emplace(0, size); return (size); } @@ -141,19 +141,18 @@ namespace ariles2 void Reader::startArrayElement() { ARILES2_ASSERT( - impl_->node_stack_.back().index_ < impl_->node_stack_.back().size_, + impl_->back().index_ < impl_->back().size_, "Internal error: array has more elements than expected."); } void Reader::endArrayElement() { - ARILES2_ASSERT(impl_->node_stack_.back().isArray(), "Internal error: expected array."); - ++impl_->node_stack_.back().index_; + impl_->shiftArray(); } void Reader::endArray() { - impl_->node_stack_.pop_back(); + impl_->pop(); } diff --git a/extra_visitors/rosparam/src/writer.cpp b/extra_visitors/rosparam/src/writer.cpp index 9f0c51f3..d43bc864 100644 --- a/extra_visitors/rosparam/src/writer.cpp +++ b/extra_visitors/rosparam/src/writer.cpp @@ -55,45 +55,44 @@ namespace ariles2 void Writer::startMapEntry(const std::string &map_name) { - if (impl_->node_stack_.empty()) + if (impl_->empty()) { impl_->root_name_ = map_name; - impl_->node_stack_.emplace_back(&impl_->root_value_); + impl_->emplace(&impl_->root_value_); } else { - impl_->node_stack_.emplace_back(&(impl_->getRawNode()[map_name])); + impl_->emplace(&(impl_->getRawNode()[map_name])); } } void Writer::endMapEntry() { - impl_->node_stack_.pop_back(); + impl_->pop(); } void Writer::startArray(const std::size_t size, const bool /*compact*/) { impl_->getRawNode().setSize(static_cast(size)); - impl_->node_stack_.emplace_back(0, size); + impl_->emplace(0, size); } void Writer::startArrayElement() { ARILES2_ASSERT( - impl_->node_stack_.back().index_ < impl_->node_stack_.back().size_, + impl_->back().index_ < impl_->back().size_, "Internal error: array has more elements than expected."); } void Writer::endArrayElement() { - ARILES2_ASSERT(impl_->node_stack_.back().isArray(), "Internal error: expected array."); - ++impl_->node_stack_.back().index_; + impl_->shiftArray(); } void Writer::endArray() { - impl_->node_stack_.pop_back(); + impl_->pop(); } diff --git a/extra_visitors/yaml_cpp/src/reader.cpp b/extra_visitors/yaml_cpp/src/reader.cpp index a4f0b5ad..6950ae70 100644 --- a/extra_visitors/yaml_cpp/src/reader.cpp +++ b/extra_visitors/yaml_cpp/src/reader.cpp @@ -27,11 +27,9 @@ namespace ariles2 { namespace impl { - class ARILES2_VISIBILITY_ATTRIBUTE Reader + class ARILES2_VISIBILITY_ATTRIBUTE Reader : public serialization::NodeStackBase { public: - /// Stack of nodes. - std::vector node_stack_; std::vector iterator_stack_; @@ -65,14 +63,14 @@ namespace ariles2 Reader::Reader(const std::string &file_name) { makeImplPtr(); - impl_->node_stack_.emplace_back(YAML::LoadFile(file_name)); + impl_->emplace(YAML::LoadFile(file_name)); } Reader::Reader(std::istream &input_stream) { makeImplPtr(); - impl_->node_stack_.emplace_back(YAML::Load(input_stream)); + impl_->emplace(YAML::Load(input_stream)); } @@ -92,14 +90,14 @@ namespace ariles2 { return (false); } - impl_->node_stack_.emplace_back(child); + impl_->emplace(child); return (true); } void Reader::endMapEntry() { ARILES2_TRACE_FUNCTION; - impl_->node_stack_.pop_back(); + impl_->pop(); } @@ -127,7 +125,7 @@ namespace ariles2 ARILES2_TRACE_FUNCTION; if (impl_->iterator_stack_.back() != impl_->getRawNode().end()) { - impl_->node_stack_.emplace_back(impl_->iterator_stack_.back()->second); + impl_->emplace(impl_->iterator_stack_.back()->second); entry_name = impl_->iterator_stack_.back()->first.as(); return (true); } @@ -138,7 +136,7 @@ namespace ariles2 { ARILES2_TRACE_FUNCTION; ++impl_->iterator_stack_.back(); - impl_->node_stack_.pop_back(); + impl_->pop(); } void Reader::endIteratedMap() @@ -157,7 +155,7 @@ namespace ariles2 ARILES2_ASSERT(impl_->getRawNode().IsSequence(), "Entry is not an array."); const std::size_t size = impl_->getRawNode().size(); - impl_->node_stack_.emplace_back(0, size); + impl_->emplace(0, size); return (size); } @@ -167,23 +165,21 @@ namespace ariles2 { ARILES2_TRACE_FUNCTION; ARILES2_ASSERT( - impl_->node_stack_.back().index_ < impl_->node_stack_.back().size_, + impl_->back().index_ < impl_->back().size_, "Internal error: array has more elements than expected."); } void Reader::endArrayElement() { - ARILES2_TRACE_FUNCTION; - ARILES2_ASSERT(impl_->node_stack_.back().isArray(), "Internal error: expected array."); - ++impl_->node_stack_.back().index_; + impl_->shiftArray(); } void Reader::endArray() { ARILES2_TRACE_FUNCTION; - impl_->node_stack_.pop_back(); + impl_->pop(); } diff --git a/include/ariles2/internal/helpers.h b/include/ariles2/internal/helpers.h index 71157982..d5e588f8 100644 --- a/include/ariles2/internal/helpers.h +++ b/include/ariles2/internal/helpers.h @@ -109,9 +109,6 @@ namespace ariles2 { - // 20 - const uint8_t num_chars_for_index_reserve = std::numeric_limits::digits10 + 1; - // intentionally not defined template class ARILES2_VISIBILITY_ATTRIBUTE PointerHandler; diff --git a/include/ariles2/visitors/serialization.h b/include/ariles2/visitors/serialization.h index e7333906..4486f420 100644 --- a/include/ariles2/visitors/serialization.h +++ b/include/ariles2/visitors/serialization.h @@ -119,6 +119,76 @@ namespace ariles2 }; + template + class NodeStackBase + { + public: + std::vector node_stack_; + + public: + [[nodiscard]] t_Node &back() + { + return (node_stack_.back()); + } + + [[nodiscard]] const t_Node &back() const + { + return (node_stack_.back()); + } + + void clear() + { + node_stack_.clear(); + } + + template + void emplace(t_Args &&...args) + { + node_stack_.emplace_back(std::forward(args)...); + } + + void pop() + { + node_stack_.pop_back(); + } + + void shiftArray() + { + ARILES2_ASSERT(back().isArray(), "Internal error: expected array."); + ++back().index_; + } + + bool empty() const + { + return (node_stack_.empty()); + } + + + // adopted from + // https://codereview.stackexchange.com/questions/195530/variadic-strcat-for-c17 + template + std::string concatenate(const t_String &...strings) const + { + std::string result; + result.reserve((strings.size() + ...)); + (result += ... += strings); + return (result); + } + + template + std::string concatWithNode(t_String &&...strings) const + { + return (concatenate(back().node_, std::forward(strings)...)); + } + + template + void concatWithNodeAndEmplace(t_String &&...strings) + { + emplace(concatWithNode(std::forward(strings)...)); + } + }; + + template class ARILES2_VISIBILITY_ATTRIBUTE PIMPLVisitor : public t_Visitor { @@ -145,7 +215,7 @@ namespace ariles2 }; - template + template using Base = visitor::Base; } // namespace serialization } // namespace ariles2 diff --git a/qa/scspell.dict b/qa/scspell.dict index 9469dd78..7e7ea6c1 100644 --- a/qa/scspell.dict +++ b/qa/scspell.dict @@ -12,6 +12,7 @@ cfgread cfgwrite classrclcpp cmakeut +codereview constexpr copyfrom copyto @@ -120,6 +121,7 @@ sighandler sigint sint sstream +stackexchange stdexcept stringbuffer stringized @@ -138,6 +140,7 @@ typeid ulonglong unistd usleep +variadic waitpid wfstream wifstream