From 7e7e3c6950721365b6c4f8e3a69db2b90cdfca29 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Thu, 16 May 2019 09:03:18 +0200 Subject: [PATCH] use optional in suffix trie --- .../stringology/indexing/SuffixTrieNaive.h | 8 +- .../src/stringology/query/SuffixTrieFactors.h | 10 +- .../src/indexes/common/IndexesNormalize.h | 9 +- .../src/indexes/stringology/SuffixArray.h | 1 - .../src/indexes/stringology/SuffixTrie.h | 44 +++--- .../src/indexes/xml/stringology/SuffixTrie.h | 6 +- alib2std/src/alib/optional | 1 + .../src/extensions/container/optional.hpp | 146 ++++++++++++++++++ alib2xml/src/container/xml/ObjectsOptional.h | 58 +++++++ 9 files changed, 242 insertions(+), 41 deletions(-) create mode 100644 alib2std/src/alib/optional create mode 100644 alib2std/src/extensions/container/optional.hpp create mode 100644 alib2xml/src/container/xml/ObjectsOptional.h diff --git a/alib2algo/src/stringology/indexing/SuffixTrieNaive.h b/alib2algo/src/stringology/indexing/SuffixTrieNaive.h index 463293a9d0..2b33b7d89a 100644 --- a/alib2algo/src/stringology/indexing/SuffixTrieNaive.h +++ b/alib2algo/src/stringology/indexing/SuffixTrieNaive.h @@ -35,19 +35,19 @@ public: template < class SymbolType > indexes::stringology::SuffixTrie < SymbolType > SuffixTrieNaive::construct ( const string::LinearString < SymbolType > & w ) { - ext::trie < SymbolType, ext::variant < void, unsigned > > trie ( ext::variant < void, unsigned > ( ( unsigned ) w.getContent ( ).size ( ) ) ); + ext::trie < SymbolType, ext::optional < unsigned > > trie ( ext::optional < unsigned > ( ( unsigned ) w.getContent ( ).size ( ) ) ); for ( unsigned i = w.getContent ( ).size ( ); i > 0; i-- ) { unsigned k = i - 1; - ext::trie < SymbolType, ext::variant < void, unsigned > > * n = & trie; + ext::trie < SymbolType, ext::optional < unsigned > > * n = & trie; // inlined slow_find_one from MI-EVY lectures while ( n->getChildren ( ).count ( w.getContent ( )[k] ) ) n = & n->getChildren ( ).find ( w.getContent ( )[k++] )->second; for ( ; k < w.getContent ( ).size ( ); k++ ) { - ext::variant < void, unsigned > node = k + 1 < w.getContent ( ).size ( ) ? ext::variant < void, unsigned >::from < void > ( ) : ext::variant < void, unsigned > ( i - 1 ); - n = & n->getChildren ( ).insert ( std::make_pair ( w.getContent ( )[k], ext::trie < SymbolType, ext::variant < void, unsigned > > ( node ) ) ).first->second; + ext::optional < unsigned > node = k + 1 < w.getContent ( ).size ( ) ? ext::optional < unsigned > ( ) : ext::optional < unsigned > ( i - 1 ); + n = & n->getChildren ( ).insert ( std::make_pair ( w.getContent ( )[k], ext::trie < SymbolType, ext::optional < unsigned > > ( node ) ) ).first->second; } } diff --git a/alib2algo/src/stringology/query/SuffixTrieFactors.h b/alib2algo/src/stringology/query/SuffixTrieFactors.h index a47b716927..69356d1f47 100644 --- a/alib2algo/src/stringology/query/SuffixTrieFactors.h +++ b/alib2algo/src/stringology/query/SuffixTrieFactors.h @@ -23,11 +23,11 @@ namespace query { class SuffixTrieFactors { template < class SymbolType > - static void accumulateResult ( const ext::trie < SymbolType, ext::variant < void, unsigned > > & trie, ext::set < unsigned > & res ) { - if ( trie.getData ( ).template is < unsigned > ( ) ) - res.insert ( trie.getData ( ).template get < unsigned > ( ) ); + static void accumulateResult ( const ext::trie < SymbolType, ext::optional < unsigned > > & trie, ext::set < unsigned > & res ) { + if ( trie.getData ( ) ) + res.insert ( trie.getData ( ).value ( ) ); - for ( const std::pair < SymbolType, ext::trie < SymbolType, ext::variant < void, unsigned > > > & child : trie.getChildren ( ) ) { + for ( const std::pair < SymbolType, ext::trie < SymbolType, ext::optional < unsigned > > > & child : trie.getChildren ( ) ) { accumulateResult ( child.second, res ); } } @@ -46,7 +46,7 @@ public: template < class SymbolType > ext::set < unsigned > SuffixTrieFactors::query ( const indexes::stringology::SuffixTrie < SymbolType > & suffixTrie, const string::LinearString < SymbolType > & string ) { - const ext::trie < SymbolType, ext::variant < void, unsigned > > * node = & suffixTrie.getRoot ( ); + const ext::trie < SymbolType, ext::optional < unsigned > > * node = & suffixTrie.getRoot ( ); for ( const SymbolType & symbol : string.getContent ( ) ) { auto iter = node->getChildren ( ).find ( symbol ); if ( iter == node->getChildren ( ).end ( ) ) { diff --git a/alib2data/src/indexes/common/IndexesNormalize.h b/alib2data/src/indexes/common/IndexesNormalize.h index 91f862a10a..b9c6fa26d0 100644 --- a/alib2data/src/indexes/common/IndexesNormalize.h +++ b/alib2data/src/indexes/common/IndexesNormalize.h @@ -11,7 +11,6 @@ #include <alib/vector> #include <alib/tuple> #include <alib/set> -#include <alib/variant> #include <alib/trie> #include <alphabet/common/SymbolNormalize.h> @@ -49,13 +48,13 @@ public: static ext::trie < DefaultSymbolType, unsigned > normalizeTrie ( ext::trie < SymbolType, unsigned > && trie ); template < class SymbolType > - static ext::trie < DefaultSymbolType, ext::variant < void, unsigned > > normalizeTrie ( ext::trie < SymbolType, ext::variant < void, unsigned > > && trie ); + static ext::trie < DefaultSymbolType, std::optional < unsigned > > normalizeTrie ( ext::trie < SymbolType, std::optional < unsigned > > && trie ); template < class SymbolType, class RankType > static ext::trie < common::ranked_symbol < DefaultSymbolType, DefaultRankType >, unsigned > normalizeRankedTrie ( ext::trie < common::ranked_symbol < SymbolType, RankType >, unsigned > && trie ); template < class SymbolType, class RankType > - static ext::trie < common::ranked_symbol < DefaultSymbolType, DefaultRankType >, ext::variant < void, unsigned > > normalizeRankedTrie ( ext::trie < common::ranked_symbol < SymbolType, RankType >, ext::variant < void, unsigned > > && trie ); + static ext::trie < common::ranked_symbol < DefaultSymbolType, DefaultRankType >, std::optional < unsigned > > normalizeRankedTrie ( ext::trie < common::ranked_symbol < SymbolType, RankType >, std::optional < unsigned > > && trie ); }; @@ -65,7 +64,7 @@ ext::trie < DefaultSymbolType, unsigned > IndexesNormalize::normalizeTrie ( ext: } template < class SymbolType > -ext::trie < DefaultSymbolType, ext::variant < void, unsigned > > IndexesNormalize::normalizeTrie ( ext::trie < SymbolType, ext::variant < void, unsigned > > && trie ) { +ext::trie < DefaultSymbolType, std::optional < unsigned > > IndexesNormalize::normalizeTrie ( ext::trie < SymbolType, std::optional < unsigned > > && trie ) { return normalizeTrieInner ( std::move ( trie ) ) ; } @@ -75,7 +74,7 @@ ext::trie < common::ranked_symbol < DefaultSymbolType, DefaultRankType >, unsign } template < class SymbolType, class RankType > -ext::trie < common::ranked_symbol < DefaultSymbolType, DefaultRankType >, ext::variant < void, unsigned > > IndexesNormalize::normalizeRankedTrie ( ext::trie < common::ranked_symbol < SymbolType, RankType >, ext::variant < void, unsigned > > && trie ) { +ext::trie < common::ranked_symbol < DefaultSymbolType, DefaultRankType >, std::optional < unsigned > > IndexesNormalize::normalizeRankedTrie ( ext::trie < common::ranked_symbol < SymbolType, RankType >, std::optional < unsigned > > && trie ) { return normalizeRankedTrieInner ( std::move ( trie ) ) ; } diff --git a/alib2data/src/indexes/stringology/SuffixArray.h b/alib2data/src/indexes/stringology/SuffixArray.h index 409b7c1275..4bcd51221c 100644 --- a/alib2data/src/indexes/stringology/SuffixArray.h +++ b/alib2data/src/indexes/stringology/SuffixArray.h @@ -27,7 +27,6 @@ #include <alib/string> #include <alib/set> #include <alib/trie> -#include <alib/variant> #include <alib/iostream> #include <alib/algorithm> #include <sstream> diff --git a/alib2data/src/indexes/stringology/SuffixTrie.h b/alib2data/src/indexes/stringology/SuffixTrie.h index cff71b0804..120cf8c088 100644 --- a/alib2data/src/indexes/stringology/SuffixTrie.h +++ b/alib2data/src/indexes/stringology/SuffixTrie.h @@ -27,7 +27,7 @@ #include <alib/string> #include <alib/set> #include <alib/trie> -#include <alib/variant> +#include <alib/optional> #include <alib/iostream> #include <alib/algorithm> #include <sstream> @@ -37,8 +37,6 @@ #include <core/components.hpp> #include <exception/CommonException.h> -#include <object/Void.h> - #include <core/normalize.hpp> #include <alphabet/common/SymbolNormalize.h> #include <indexes/common/IndexesNormalize.h> @@ -50,7 +48,7 @@ namespace stringology { class GeneralAlphabet; /** - * \brief Suffix trie string index. Tree like representation of all suffixes. Nodes of the trie are either containing index of the suffix or void. The parent child relationship of nodes is represented by single symbol. The class does not checks whether the trie actually is suffix trie. + * \brief Suffix trie string index. Tree like representation of all suffixes. Nodes of the trie are optionally containing index of the suffix. The parent child relationship of nodes is represented by single symbol. The class does not checks whether the trie actually is suffix trie. * * \tparam SymbolType type of symbols of indexed string */ @@ -59,18 +57,18 @@ class SuffixTrie final : public ext::CompareOperators < SuffixTrie < SymbolType /** * Representation of the suffix trie. */ - ext::trie < SymbolType, ext::variant < void, unsigned > > m_trie; + ext::trie < SymbolType, ext::optional < unsigned > > m_trie; /** * \brief Checks edges of the raw suffix trie, whether they are over the specified alphabet. * * \throws exception::CommonException if there is a symbol on trie edges not present in the alphabet. */ - void checkTrie ( const ext::trie < SymbolType, ext::variant < void, unsigned > > & trie ); + void checkTrie ( const ext::trie < SymbolType, ext::optional < unsigned > > & trie ); public: /** - * Creates a new instance of the index over concrete alphabet and content initialized to root containing void. + * Creates a new instance of the index over concrete alphabet and content initialized to empty root. * * \param edgeAlphabet the alphabet of symbols on node to node edges. */ @@ -82,28 +80,28 @@ public: * \param edgeAlphabet the alphabet of symbols on node to node edges. * \param trie the representation of suffix trie. */ - explicit SuffixTrie ( ext::set < SymbolType > edgeAlphabet, ext::trie < SymbolType, ext::variant < void, unsigned > > trie ); + explicit SuffixTrie ( ext::set < SymbolType > edgeAlphabet, ext::trie < SymbolType, ext::optional < unsigned > > trie ); /** * Creates a new instance of the index based on raw suffix trie. * * \param trie the representation of suffix trie. */ - explicit SuffixTrie ( ext::trie < SymbolType, ext::variant < void, unsigned > > trie ); + explicit SuffixTrie ( ext::trie < SymbolType, ext::optional < unsigned > > trie ); /** * Getter of the raw suffix trie. * * \return root node of the trie */ - const ext::trie < SymbolType, ext::variant < void, unsigned > > & getRoot ( ) const &; + const ext::trie < SymbolType, ext::optional < unsigned > > & getRoot ( ) const &; /** * Getter of the raw suffix trie. * * \return root node of the trie */ - ext::trie < SymbolType, ext::variant < void, unsigned > > && getRoot ( ) &&; + ext::trie < SymbolType, ext::optional < unsigned > > && getRoot ( ) &&; /** * Getter of the alphabet of the indexed string. @@ -128,7 +126,7 @@ public: * * \param tree root node to set */ - void setTree ( ext::trie < SymbolType, ext::variant < void, unsigned > > tree ); + void setTree ( ext::trie < SymbolType, ext::optional < unsigned > > tree ); /** * Remover of a symbol from the alphabet. @@ -177,21 +175,21 @@ namespace indexes { namespace stringology { template < class SymbolType > -SuffixTrie < SymbolType >::SuffixTrie ( ext::set < SymbolType > edgeAlphabet ) : SuffixTrie ( std::move ( edgeAlphabet ), ext::trie < SymbolType, ext::variant < void, unsigned > > ( ext::variant < void, unsigned >::template from < void > ( ) ) ) { +SuffixTrie < SymbolType >::SuffixTrie ( ext::set < SymbolType > edgeAlphabet ) : SuffixTrie ( std::move ( edgeAlphabet ), ext::trie < SymbolType, ext::optional < unsigned > > ( ext::optional < unsigned > ( ) ) ) { } template < class SymbolType > -SuffixTrie < SymbolType >::SuffixTrie ( ext::set < SymbolType > edgeAlphabet, ext::trie < SymbolType, ext::variant < void, unsigned > > trie ) : core::Components < SuffixTrie, ext::set < SymbolType >, component::Set, GeneralAlphabet > ( std::move ( edgeAlphabet ) ), m_trie ( std::move ( trie ) ) { +SuffixTrie < SymbolType >::SuffixTrie ( ext::set < SymbolType > edgeAlphabet, ext::trie < SymbolType, ext::optional < unsigned > > trie ) : core::Components < SuffixTrie, ext::set < SymbolType >, component::Set, GeneralAlphabet > ( std::move ( edgeAlphabet ) ), m_trie ( std::move ( trie ) ) { checkTrie ( this->m_trie ); } template < class SymbolType > -SuffixTrie < SymbolType >::SuffixTrie ( ext::trie < SymbolType, ext::variant < void, unsigned > > trie ) : SuffixTrie ( computeMinimalEdgeAlphabet ( trie ), trie ) { +SuffixTrie < SymbolType >::SuffixTrie ( ext::trie < SymbolType, ext::optional < unsigned > > trie ) : SuffixTrie ( computeMinimalEdgeAlphabet ( trie ), trie ) { } template < class SymbolType > -void SuffixTrie < SymbolType >::checkTrie ( const ext::trie < SymbolType, ext::variant < void, unsigned > > & trie ) { - for ( const std::pair < const SymbolType, ext::trie < SymbolType, ext::variant < void, unsigned > > > & child : trie.getChildren ( ) ) { +void SuffixTrie < SymbolType >::checkTrie ( const ext::trie < SymbolType, ext::optional < unsigned > > & trie ) { + for ( const std::pair < const SymbolType, ext::trie < SymbolType, ext::optional < unsigned > > > & child : trie.getChildren ( ) ) { if ( ! getAlphabet ( ).count ( child.first ) ) throw exception::CommonException ( "Symbol " + ext::to_string ( child.first ) + "not in the alphabet." ); checkTrie ( child.second ); @@ -199,17 +197,17 @@ void SuffixTrie < SymbolType >::checkTrie ( const ext::trie < SymbolType, ext::v } template < class SymbolType > -const ext::trie < SymbolType, ext::variant < void, unsigned > > & SuffixTrie < SymbolType >::getRoot ( ) const & { +const ext::trie < SymbolType, ext::optional < unsigned > > & SuffixTrie < SymbolType >::getRoot ( ) const & { return m_trie; } template < class SymbolType > -ext::trie < SymbolType, ext::variant < void, unsigned > > && SuffixTrie < SymbolType >::getRoot ( ) && { +ext::trie < SymbolType, ext::optional < unsigned > > && SuffixTrie < SymbolType >::getRoot ( ) && { return std::move ( m_trie ); } template < class SymbolType > -void SuffixTrie < SymbolType >::setTree ( ext::trie < SymbolType, ext::variant < void, unsigned > > trie ) { +void SuffixTrie < SymbolType >::setTree ( ext::trie < SymbolType, ext::optional < unsigned > > trie ) { checkTrie ( trie ); this->m_trie = std::move ( trie ).clone ( ); } @@ -253,8 +251,8 @@ class SetConstraint < indexes::stringology::SuffixTrie < SymbolType >, SymbolTyp * * \returns true if the symbol is used, false othervise */ - static bool used ( const ext::trie < SymbolType, ext::variant < void, unsigned > > & trie, const SymbolType & symbol ) { - for ( const std::pair < const SymbolType, ext::trie < SymbolType, ext::variant < void, unsigned > > > & child : trie.getChildren ( ) ) { + static bool used ( const ext::trie < SymbolType, ext::optional < unsigned > > & trie, const SymbolType & symbol ) { + for ( const std::pair < const SymbolType, ext::trie < SymbolType, ext::optional < unsigned > > > & child : trie.getChildren ( ) ) { if ( symbol == child.first || checkTrie ( trie, child.second ) ) return true; } @@ -305,7 +303,7 @@ template < class SymbolType > struct normalize < indexes::stringology::SuffixTrie < SymbolType > > { static indexes::stringology::SuffixTrie < > eval ( indexes::stringology::SuffixTrie < SymbolType > && value ) { ext::set < DefaultSymbolType > alphabet = alphabet::SymbolNormalize::normalizeAlphabet ( std::move ( value ).getAlpahet ( ) ); - ext::trie < DefaultSymbolType, ext::variant < void, unsigned > > trie = indexes::IndexesNormalize::normalizeTrie ( std::move ( value ).getRoot ( ) ); + ext::trie < DefaultSymbolType, ext::optional < unsigned > > trie = indexes::IndexesNormalize::normalizeTrie ( std::move ( value ).getRoot ( ) ); return indexes::stringology::SuffixTrie < > ( std::move ( alphabet ), std::move ( trie ) ); } diff --git a/alib2data/src/indexes/xml/stringology/SuffixTrie.h b/alib2data/src/indexes/xml/stringology/SuffixTrie.h index 72934b7da4..a29862b996 100644 --- a/alib2data/src/indexes/xml/stringology/SuffixTrie.h +++ b/alib2data/src/indexes/xml/stringology/SuffixTrie.h @@ -32,7 +32,7 @@ #include <object/xml/Void.h> #include <primitive/xml/Unsigned.h> #include <container/xml/ObjectsSet.h> -#include <container/xml/ObjectsVariant.h> +#include <container/xml/ObjectsOptional.h> #include <container/xml/ObjectsTrie.h> namespace core { @@ -49,7 +49,7 @@ template < class SymbolType > indexes::stringology::SuffixTrie < SymbolType > xmlApi < indexes::stringology::SuffixTrie < SymbolType > >::parse ( ext::deque < sax::Token >::iterator & input ) { sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, xmlTagName ( ) ); ext::set < SymbolType > edgeAlphabet = core::xmlApi < ext::set < SymbolType > >::parse ( input ); - ext::trie < SymbolType, ext::variant < void, unsigned > > root = core::xmlApi < ext::trie < SymbolType, ext::variant < void, unsigned > > >::parse ( input ); + ext::trie < SymbolType, ext::optional < unsigned > > root = core::xmlApi < ext::trie < SymbolType, ext::optional < unsigned > > >::parse ( input ); indexes::stringology::SuffixTrie < SymbolType > res ( std::move ( edgeAlphabet ), std::move ( root ) ); sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, xmlTagName ( ) ); @@ -70,7 +70,7 @@ template < class SymbolType > void xmlApi < indexes::stringology::SuffixTrie < SymbolType > >::compose ( ext::deque < sax::Token > & output, const indexes::stringology::SuffixTrie < SymbolType > & index ) { output.emplace_back ( xmlTagName ( ), sax::Token::TokenType::START_ELEMENT ); core::xmlApi < ext::set < SymbolType > >::compose ( output, index.getAlphabet ( ) ); - core::xmlApi < ext::trie < SymbolType, ext::variant < void, unsigned > > >::compose ( output, index.getRoot ( ) ); + core::xmlApi < ext::trie < SymbolType, ext::optional < unsigned > > >::compose ( output, index.getRoot ( ) ); output.emplace_back ( xmlTagName ( ), sax::Token::TokenType::END_ELEMENT ); } diff --git a/alib2std/src/alib/optional b/alib2std/src/alib/optional new file mode 100644 index 0000000000..0d36636307 --- /dev/null +++ b/alib2std/src/alib/optional @@ -0,0 +1 @@ +#include <extensions/container/optional.hpp> diff --git a/alib2std/src/extensions/container/optional.hpp b/alib2std/src/extensions/container/optional.hpp new file mode 100644 index 0000000000..2c6ce90f09 --- /dev/null +++ b/alib2std/src/extensions/container/optional.hpp @@ -0,0 +1,146 @@ +/** + * optional.hpp + * + * This file is part of Algorithms library toolkit. + * Copyright (C) 2017 Jan Travnicek (jan.travnicek@fit.cvut.cz) + + * Algorithms library toolkit is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * Algorithms library toolkit is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with Algorithms library toolkit. If not, see <http://www.gnu.org/licenses/>. + * + * https://gist.github.com/tibordp/6909880 + * + * Created on: May 16, 2019 + * Created: Jan Travnicek + */ + +#ifndef __OPTIONAL_HPP_ +#define __OPTIONAL_HPP_ + +#include <optional> + +#include <extensions/compare.hpp> + +namespace ext { + +template < typename T > +class optional : public std::optional < T > { +public: + /** + * Inherit constructors of the standard optional + */ + using std::optional< T >::optional; + + /** + * Inherit operator = of the standard optional + */ + using std::optional< T >::operator =; +#ifndef __clang__ + + /** + * Default constructor needed by g++ since it is not inherited + */ + optional ( ) = default; + + /** + * Copy constructor needed by g++ since it is not inherited + */ + optional ( const optional & other ) = default; + + /** + * Move constructor needed by g++ since it is not inherited + */ + optional ( optional && other ) = default; + + /** + * Copy operator = needed by g++ since it is not inherited + */ + optional & operator = ( optional && other ) = default; + + /** + * Move operator = needed by g++ since it is not inherited + */ + optional & operator = ( const optional & other ) = default; +#endif +}; + +/** + * \brief + * Specialisation of the compare structure implementing the three-way comparison. + * + * \tparam T type in the optional + */ +template < typename T > +struct compare < ext::optional < T > > { + + /** + * \brief + * Implementation of the three-way comparison. + * + * \param first the left operand of the comparison + * \param second the right operand of the comparison + * + * \return negative value of left < right, positive value if left > right, zero if left == right + */ + int operator ( ) ( const ext::optional < T > & first, const ext::optional < T > & second ) const { + if ( ! first && ! second ) + return 0; + if ( first && ! second ) + return 1; + if ( ! first && second ) + return -1; + + static ext::compare < T > comp; + return comp ( first.value ( ), second.value ( ) ); + } +}; + +/** + * \brief + * Operator to print the optional to the output stream. + * + * \param out the output stream + * \param optional the optional to print + * + * \tparam T the type of value inside the optional + * + * \return the output stream from the \p out + */ +template< class T > +std::ostream & operator << ( std::ostream & out, const ext::optional < T > & optional ) { + if ( ! optional ) + return out << "void"; + else + return out << optional.value ( ); +} + + +/** + * \brief + * Overload of to_string function. + * + * \param value the optional to be converted to string + * + * \tparam T the type of values inside the optional + * + * \return string representation + */ +template < class T > +std::string to_string ( const ext::optional < T > & value ) { + std::stringstream ss; + ss << value; + return ss.str(); +} + +} /* namespace ext */ + +#endif /* __OPTIONAL_HPP_ */ diff --git a/alib2xml/src/container/xml/ObjectsOptional.h b/alib2xml/src/container/xml/ObjectsOptional.h new file mode 100644 index 0000000000..9dc16e2aa8 --- /dev/null +++ b/alib2xml/src/container/xml/ObjectsOptional.h @@ -0,0 +1,58 @@ +/* + * Optional.h + * + * Created on: Apr 1, 2013 + * Author: Jan Travnicek + */ + +#ifndef _XML_OBJECTS_OPTIONAL_H_ +#define _XML_OBJECTS_OPTIONAL_H_ + +#include <alib/optional> +#include <exception/CommonException.h> +#include <core/xmlApi.hpp> + +namespace core { + +template < typename T > +struct xmlApi < ext::optional < T > > { + static ext::optional < T > parse ( ext::deque < sax::Token >::iterator & input ); + static bool first ( const ext::deque < sax::Token >::const_iterator & input ); + static std::string xmlTagName ( ); + static void compose ( ext::deque < sax::Token > & output, const ext::optional < T > & data ); +}; + +template < typename T > +ext::optional < T > xmlApi < ext::optional < T > >::parse ( ext::deque < sax::Token >::iterator & input ) { + if ( sax::FromXMLParserHelper::isToken ( input, sax::Token::TokenType::START_ELEMENT, "void" ) ) { + ++input; + sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "void" ); + return ext::optional < T > ( ); + } else { + return ext::optional < T > ( core::xmlApi < T >::parse ( input ) ); + } +} + +template < typename T > +bool xmlApi < ext::optional < T > >::first ( const ext::deque < sax::Token >::const_iterator & input ) { + return sax::FromXMLParserHelper::isToken ( input, sax::Token::TokenType::START_ELEMENT, "void" ) || xmlApi < T >::first ( input ); +} + +template < typename T > +std::string xmlApi < ext::optional < T > >::xmlTagName ( ) { + throw exception::CommonException ( "Optional does not have xmlTagName." ); +} + +template < typename T > +void xmlApi < ext::optional < T > >::compose ( ext::deque < sax::Token > & output, const ext::optional < T > & input ) { + if ( ! input ) { + output.emplace_back("void", sax::Token::TokenType::START_ELEMENT); + output.emplace_back("void", sax::Token::TokenType::END_ELEMENT); + } else { + core::xmlApi < T >::compose ( output, input.value ( ) ); + } +} + +} /* namespace core */ + +#endif /* _XML_OBJECTS_OPTIONAL_H_ */ -- GitLab