From f6ba975e644732dc1795d14f1876688c471280f7 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Tue, 16 Sep 2014 20:19:04 +0200 Subject: [PATCH] Map container --- alib2data/src/Api.cpp | 12 ++++ alib2data/src/Api.hpp | 23 ++++++++ alib2data/src/container/ContainerBase.h | 3 +- alib2data/src/container/ContainerFeatures.h | 3 +- .../src/container/ContainerFromXMLParser.cpp | 21 ++++++- .../src/container/ContainerFromXMLParser.hpp | 21 +++++++ .../src/container/ContainerToXMLComposer.cpp | 12 ++++ .../src/container/ContainerToXMLComposer.hpp | 18 ++++++ alib2data/src/container/ObjectsMap.cpp | 55 +++++++++++++++++++ alib2data/src/container/ObjectsMap.h | 47 ++++++++++++++++ alib2data/src/object/ObjectBase.h | 5 +- 11 files changed, 213 insertions(+), 7 deletions(-) create mode 100644 alib2data/src/container/ObjectsMap.cpp create mode 100644 alib2data/src/container/ObjectsMap.h diff --git a/alib2data/src/Api.cpp b/alib2data/src/Api.cpp index 9e003959d9..741bf71c58 100644 --- a/alib2data/src/Api.cpp +++ b/alib2data/src/Api.cpp @@ -63,6 +63,14 @@ std::list<sax::Token> api<container::ObjectsPair>::compose(const container::Obje return ToXMLComposers::containerComposer.compose(data); } +container::ObjectsMap api<container::ObjectsMap>::parse(std::list<sax::Token>& input) { + return FromXMLParsers::containerParser.parseObjectsMap(input); +} + +std::list<sax::Token> api<container::ObjectsMap>::compose(const container::ObjectsMap& data) { + return ToXMLComposers::containerComposer.compose(data); +} + alib::Object api<alib::Object>::parse(std::list<sax::Token>& input) { return FromXMLParsers::objectParser.parseObject(input); } @@ -472,6 +480,10 @@ void ToXMLComposers::Visit(void* data, const container::ObjectsPair& container) *((std::list<sax::Token>*) data) = std::move(api<container::ObjectsPair>::compose(container)); } +void ToXMLComposers::Visit(void* data, const container::ObjectsMap& container) const { + *((std::list<sax::Token>*) data) = std::move(api<container::ObjectsMap>::compose(container)); +} + void ToXMLComposers::Visit(void* data, const exception::AlibException& symbol) const { *((std::list<sax::Token>*) data) = std::move(api<exception::AlibException>::compose(symbol)); } diff --git a/alib2data/src/Api.hpp b/alib2data/src/Api.hpp index ba9731cca6..e4dea10371 100644 --- a/alib2data/src/Api.hpp +++ b/alib2data/src/Api.hpp @@ -72,6 +72,18 @@ struct api<container::ObjectsPair> { static std::list<sax::Token> compose(const container::ObjectsPair& data); }; +template<typename T, typename R> +struct api<std::map<T, R>> { + static std::map<T, R> parse(std::list<sax::Token>& input); + static std::list<sax::Token> compose(const std::map<T, R>& data); +}; + +template<> +struct api<container::ObjectsMap> { + static container::ObjectsMap parse(std::list<sax::Token>& input); + static std::list<sax::Token> compose(const container::ObjectsMap& data); +}; + template<> struct api<Object> { @@ -459,6 +471,7 @@ class ToXMLComposers : public VisitableObjectBase::const_visitor_type { void Visit(void*, const container::ObjectsSet& set) const; void Visit(void*, const container::ObjectsVector& set) const; void Visit(void*, const container::ObjectsPair& set) const; + void Visit(void*, const container::ObjectsMap& set) const; public: static const label::LabelToXMLComposer labelComposer; @@ -504,6 +517,16 @@ std::list<sax::Token> api<std::pair<T, R>>::compose(const std::pair<T, R>& input return ToXMLComposers::containerComposer.compose<T, R>(input); } +template<typename T, typename R> +std::map<T, R> api<std::map<T, R>>::parse(std::list<sax::Token>& input) { + return FromXMLParsers::containerParser.parseMap<T, R>(input); +} + +template<typename T, typename R> +std::list<sax::Token> api<std::map<T, R>>::compose(const std::map<T, R>& input) { + return ToXMLComposers::containerComposer.compose<T, R>(input); +} + } /* namespace alib */ #endif /* FROM_XML_PARSERS_HPP_ */ diff --git a/alib2data/src/container/ContainerBase.h b/alib2data/src/container/ContainerBase.h index 82577ea329..c9eb75c43d 100644 --- a/alib2data/src/container/ContainerBase.h +++ b/alib2data/src/container/ContainerBase.h @@ -16,7 +16,8 @@ namespace container { typedef std::acceptor_base< container::ObjectsSet, container::ObjectsVector, - container::ObjectsPair + container::ObjectsPair, + container::ObjectsMap > VisitableContainerBase; /** diff --git a/alib2data/src/container/ContainerFeatures.h b/alib2data/src/container/ContainerFeatures.h index c91809af68..f8c5a29c34 100644 --- a/alib2data/src/container/ContainerFeatures.h +++ b/alib2data/src/container/ContainerFeatures.h @@ -13,7 +13,8 @@ namespace container { enum class FEATURES { SET, VECTOR, - PAIR + PAIR, + MAP }; } /* namespace container */ diff --git a/alib2data/src/container/ContainerFromXMLParser.cpp b/alib2data/src/container/ContainerFromXMLParser.cpp index 0fe6d6cd1a..29ff8913ab 100644 --- a/alib2data/src/container/ContainerFromXMLParser.cpp +++ b/alib2data/src/container/ContainerFromXMLParser.cpp @@ -11,7 +11,7 @@ namespace container { bool ContainerFromXMLParser::first(std::list<sax::Token>& input) const { - if(isToken(input, sax::Token::TokenType::START_ELEMENT, "set") || isToken(input, sax::Token::TokenType::START_ELEMENT, "vector") || isToken(input, sax::Token::TokenType::START_ELEMENT, "pair")) { + if(isToken(input, sax::Token::TokenType::START_ELEMENT, "set") || isToken(input, sax::Token::TokenType::START_ELEMENT, "vector") || isToken(input, sax::Token::TokenType::START_ELEMENT, "pair") || isToken(input, sax::Token::TokenType::START_ELEMENT, "map")) { return true; } else { return false; @@ -19,7 +19,7 @@ bool ContainerFromXMLParser::first(std::list<sax::Token>& input) const { } Container ContainerFromXMLParser::parseContainer(std::list<sax::Token>& input) const { - return parseContainer(input, std::set<FEATURES>({FEATURES::SET, FEATURES::VECTOR, FEATURES::PAIR})); + return parseContainer(input, std::set<FEATURES>({FEATURES::SET, FEATURES::VECTOR, FEATURES::PAIR, FEATURES::MAP})); } Container ContainerFromXMLParser::parseContainer(std::list<sax::Token>& input, const std::set<FEATURES>& features) const { @@ -32,8 +32,11 @@ Container ContainerFromXMLParser::parseContainer(std::list<sax::Token>& input, c } else if(isToken(input, sax::Token::TokenType::START_ELEMENT, "pair")) { if(!features.count(FEATURES::PAIR)) throw exception::AlibException(); return Container(parseObjectsPair(input)); + } else if(isToken(input, sax::Token::TokenType::START_ELEMENT, "map")) { + if(!features.count(FEATURES::MAP)) throw exception::AlibException(); + return Container(parseObjectsMap(input)); } else { - throw sax::ParserException(sax::Token("set / vector", sax::Token::TokenType::START_ELEMENT), input.front()); + throw sax::ParserException(sax::Token("set / vector / pair / map", sax::Token::TokenType::START_ELEMENT), input.front()); } } @@ -75,5 +78,17 @@ ObjectsPair ContainerFromXMLParser::parseObjectsPair(std::list<sax::Token>& inpu return pair; } +ObjectsMap ContainerFromXMLParser::parseObjectsMap(std::list<sax::Token>& input) const { + popToken(input, sax::Token::TokenType::START_ELEMENT, "map"); + + ObjectsMap map; + while(isTokenType(input, sax::Token::TokenType::START_ELEMENT)) { + map.insert(alib::api<std::pair<alib::Object, alib::Object>>::parse(input)); + } + + popToken(input, sax::Token::TokenType::END_ELEMENT, "map"); + return map; +} + } /* namespace container */ diff --git a/alib2data/src/container/ContainerFromXMLParser.hpp b/alib2data/src/container/ContainerFromXMLParser.hpp index dba7e1b8d6..ab4d4248cb 100644 --- a/alib2data/src/container/ContainerFromXMLParser.hpp +++ b/alib2data/src/container/ContainerFromXMLParser.hpp @@ -13,6 +13,8 @@ #include "ObjectsSet.h" #include "ObjectsVector.h" +#include "ObjectsPair.h" +#include "ObjectsMap.h" #include "Container.h" @@ -47,6 +49,11 @@ class ContainerFromXMLParser : public sax::FromXMLParserHelper { ObjectsPair parseObjectsPair(std::list<sax::Token>& input) const; + template<typename T, typename R> + std::map<T, R> parseMap(std::list<sax::Token>& input) const; + + ObjectsMap parseObjectsMap(std::list<sax::Token>& input) const; + template<typename T> friend class alib::api; public: @@ -98,6 +105,20 @@ std::pair<T, R> ContainerFromXMLParser::parsePair(std::list<sax::Token>& input) return std::make_pair(first, second); } +template<typename T, typename R> +std::map<T, R> ContainerFromXMLParser::parseMap(std::list<sax::Token>& input) const { + popToken(input, sax::Token::TokenType::START_ELEMENT, "map"); + + std::map<T, R> map; + + while(isTokenType(input, sax::Token::TokenType::START_ELEMENT)) { + map.insert(alib::api<std::pair<T, R>>::parse(input)); + } + + popToken(input, sax::Token::TokenType::END_ELEMENT, "map"); + return map; +} + } /* namespace container */ #endif /* CONTAINER_FROM_XML_PARSER_H_ */ diff --git a/alib2data/src/container/ContainerToXMLComposer.cpp b/alib2data/src/container/ContainerToXMLComposer.cpp index edbdbe9d1e..ecfad0e3c7 100644 --- a/alib2data/src/container/ContainerToXMLComposer.cpp +++ b/alib2data/src/container/ContainerToXMLComposer.cpp @@ -56,5 +56,17 @@ std::list<sax::Token> ContainerToXMLComposer::compose(const ObjectsPair& contain return out; } +std::list<sax::Token> ContainerToXMLComposer::compose(const ObjectsMap& container) const { + std::list<sax::Token> out; + out.push_back(sax::Token("map", sax::Token::TokenType::START_ELEMENT)); + + for(const std::pair<alib::Object, alib::Object>& item : container) { + out.splice(out.end(), alib::api<std::pair<alib::Object, alib::Object>>::compose(item)); + } + + out.push_back(sax::Token("map", sax::Token::TokenType::END_ELEMENT)); + return out; +} + } /* namespace container */ diff --git a/alib2data/src/container/ContainerToXMLComposer.hpp b/alib2data/src/container/ContainerToXMLComposer.hpp index 4d9581e8a7..7e6f4fa0c3 100644 --- a/alib2data/src/container/ContainerToXMLComposer.hpp +++ b/alib2data/src/container/ContainerToXMLComposer.hpp @@ -58,6 +58,11 @@ class ContainerToXMLComposer { std::list<sax::Token> compose(const ObjectsPair& container) const; + template<typename T, typename R> + std::list<sax::Token> compose(const std::map<T, R>& container) const; + + std::list<sax::Token> compose(const ObjectsMap& container) const; + template<typename T> friend class alib::api; }; @@ -105,6 +110,19 @@ std::list<sax::Token> ContainerToXMLComposer::compose(const std::pair<T, R>& con return out; } +template<typename T, typename R> +std::list<sax::Token> ContainerToXMLComposer::compose(const std::map<T, R>& container) const { + std::list<sax::Token> out; + out.push_back(sax::Token("map", sax::Token::TokenType::START_ELEMENT)); + + for(const std::pair<T, R>& item : container) { + out.splice(out.end(), alib::api<std::pair<T, R>>::compose(item)); + } + + out.push_back(sax::Token("map", sax::Token::TokenType::END_ELEMENT)); + return out; +} + } /* namespace container */ #endif /* CONTAINER_TO_XML_COMPOSER_H_ */ diff --git a/alib2data/src/container/ObjectsMap.cpp b/alib2data/src/container/ObjectsMap.cpp new file mode 100644 index 0000000000..f8b07ca4bb --- /dev/null +++ b/alib2data/src/container/ObjectsMap.cpp @@ -0,0 +1,55 @@ +/* + * Map.cpp + * + * Created on: Apr 1, 2013 + * Author: Jan Travnicek + */ + +#include "ObjectsMap.h" +#include "../std/map.hpp" + +#include <cstdlib> +#include <iostream> +#include <sstream> + +namespace container { + +ContainerBase* ObjectsMap::clone() const { + return new ObjectsMap(*this); +} + +ContainerBase* ObjectsMap::plunder() && { + return new ObjectsMap(std::move(*this)); +} + +bool ObjectsMap::operator==(const ObjectBase& other) const { + return other == *this; +} + +bool ObjectsMap::operator<(const ObjectBase& other) const { + return other > *this; +} + +bool ObjectsMap::operator>(const ObjectBase& other) const { + return other < *this; +} + +bool ObjectsMap::operator==(const ObjectsMap& other) const { + return static_cast<const std::map<alib::Object, alib::Object>>(*this) == static_cast<const std::map<alib::Object, alib::Object>>(other); +} + +bool ObjectsMap::operator<(const ObjectsMap& other) const { + return static_cast<const std::map<alib::Object, alib::Object>>(*this) < static_cast<const std::map<alib::Object, alib::Object>>(other); +} + +void ObjectsMap::operator>>(std::ostream& os) const { + os << *this; +} + +ObjectsMap::operator std::string() const { + std::stringstream ss; + ss << *this; + return std::move(ss).str(); +} + +} /* namespace container */ diff --git a/alib2data/src/container/ObjectsMap.h b/alib2data/src/container/ObjectsMap.h new file mode 100644 index 0000000000..71503f3a2f --- /dev/null +++ b/alib2data/src/container/ObjectsMap.h @@ -0,0 +1,47 @@ +/* + * Map.h + * + * Created on: Apr 1, 2013 + * Author: Jan Travnicek + */ + +#ifndef OBJECTS_MAP_H_ +#define OBJECTS_MAP_H_ + +#include <map> +#include <string> + +#include "../object/Object.h" +#include "ContainerBase.h" + +namespace container { + +/** + * Basic container from which are derived all other containers. + * Contains reason why the container occured. + */ +class ObjectsMap : public std::map<alib::Object, alib::Object>, public std::acceptor<ObjectsMap, VisitableContainerBase, std::acceptor<ObjectsMap, alib::VisitableObjectBase, ContainerBase> > { +public: + virtual ContainerBase* clone() const; + + virtual ContainerBase* plunder() &&; + + virtual bool operator>(const alib::ObjectBase& other) const; + virtual bool operator==(const alib::ObjectBase& other) const; + virtual bool operator<(const alib::ObjectBase& other) const; + + virtual bool operator==(const ObjectsMap& other) const; + virtual bool operator<(const ObjectsMap& other) const; + + virtual void operator>>(std::ostream& os) const; + + virtual operator std::string() const; + + virtual int selfTypeId() const { + return typeId(*this); + } +}; + +} /* namespace container */ + +#endif /* OBJECTS_MAP_H_ */ diff --git a/alib2data/src/object/ObjectBase.h b/alib2data/src/object/ObjectBase.h index 49e82fafc6..3257428e4f 100644 --- a/alib2data/src/object/ObjectBase.h +++ b/alib2data/src/object/ObjectBase.h @@ -93,6 +93,7 @@ namespace container { class ObjectsSet; class ObjectsVector; class ObjectsPair; +class ObjectsMap; } @@ -106,7 +107,7 @@ typedef std::acceptor_base< regexp::UnboundedRegExp, regexp::FormalRegExp, string::Epsilon, string::LinearString, string::CyclicString, alphabet::LabeledSymbol, alphabet::BlankSymbol, alphabet::BottomOfTheStackSymbol, alphabet::EndSymbol, - container::ObjectsSet, container::ObjectsVector, container::ObjectsPair + container::ObjectsSet, container::ObjectsVector, container::ObjectsPair, container::ObjectsMap > VisitableObjectBase; class ObjectBase : @@ -119,7 +120,7 @@ class ObjectBase : regexp::UnboundedRegExp, regexp::FormalRegExp, string::Epsilon, string::LinearString, string::CyclicString, alphabet::LabeledSymbol, alphabet::BlankSymbol, alphabet::BottomOfTheStackSymbol, alphabet::EndSymbol, - container::ObjectsSet, container::ObjectsVector, container::ObjectsPair + container::ObjectsSet, container::ObjectsVector, container::ObjectsPair, container::ObjectsMap >, public VisitableObjectBase { }; -- GitLab