diff --git a/alib2algo/src/automaton/transform/Compaction.h b/alib2algo/src/automaton/transform/Compaction.h index 24dfa1560a93e8dc7b893706501815b1f78185c9..6864ae30b40caa7d9b63326411c7fc62cd7798e0 100644 --- a/alib2algo/src/automaton/transform/Compaction.h +++ b/alib2algo/src/automaton/transform/Compaction.h @@ -91,7 +91,7 @@ automaton::CompactNFA < SymbolType, StateType > Compaction::convert(const automa ext::vector < SymbolType > path { symbol }; - ext::range < typename ext::map < ext::pair < StateType, SymbolType >, StateType >::const_iterator > transitions; + ext::iterator_range < typename ext::map < ext::pair < StateType, SymbolType >, StateType >::const_iterator > transitions; // only 1 child and nonfinal while((transitions = automaton.getTransitionsFromState(q)).size() == 1 && automaton.getFinalStates().count(q) == 0) { const std::pair<ext::pair<StateType, SymbolType>, StateType>& transition = * transitions.begin(); diff --git a/alib2algo_experimental/src/grammar/parsing/SLR1ParseTable.cpp b/alib2algo_experimental/src/grammar/parsing/SLR1ParseTable.cpp index cd77940f7668f08bb82453aa0f4cb5f4f4a62e13..1e4676c05a676aac717a767447c6da30a3186601 100644 --- a/alib2algo_experimental/src/grammar/parsing/SLR1ParseTable.cpp +++ b/alib2algo_experimental/src/grammar/parsing/SLR1ParseTable.cpp @@ -31,7 +31,7 @@ LRActionTable SLR1ParseTable::getActionTable ( grammar::CFG < > originalGrammar automaton::DFA<> parsingAutomaton = LR0Parser::getAutomaton ( originalGrammar ); for ( const DefaultStateType & state : parsingAutomaton.getStates ( ) ) { LR0Items items = static_cast < const label::LR0ItemsLabel & > ( state . getData ( ) ) . getItems ( ); - ext::range < ext::map < ext::pair < DefaultStateType, DefaultSymbolType >, DefaultStateType >::const_iterator > transitionsFromCurrentStateRange = parsingAutomaton.getTransitionsFromState ( state ); + ext::iterator_range < ext::map < ext::pair < DefaultStateType, DefaultSymbolType >, DefaultStateType >::const_iterator > transitionsFromCurrentStateRange = parsingAutomaton.getTransitionsFromState ( state ); ext::map < ext::pair < DefaultStateType, DefaultSymbolType >, DefaultStateType > transitionsFromCurrentState ( transitionsFromCurrentStateRange.begin ( ), transitionsFromCurrentStateRange.end ( ) ); for ( const LR0Items::value_type & nonterminalItems : items ) { DefaultSymbolType leftHandSide = nonterminalItems.first; @@ -73,7 +73,7 @@ LRGotoTable SLR1ParseTable::getGotoTable ( grammar::CFG < > originalGrammar ) { grammar::CFG < > augmentedGrammar = LRParser::getAugmentedGrammar ( originalGrammar ); automaton::DFA<> parsingAutomaton = LR0Parser::getAutomaton ( originalGrammar ); for ( const DefaultStateType & state : parsingAutomaton.getStates ( ) ) { - ext::range < ext::map < ext::pair < DefaultStateType, DefaultSymbolType >, DefaultStateType >::const_iterator > transitionsFromCurrentStateRange = parsingAutomaton.getTransitionsFromState ( state ); + ext::iterator_range < ext::map < ext::pair < DefaultStateType, DefaultSymbolType >, DefaultStateType >::const_iterator > transitionsFromCurrentStateRange = parsingAutomaton.getTransitionsFromState ( state ); ext::map < ext::pair < DefaultStateType, DefaultSymbolType >, DefaultStateType > transitionsFromCurrentState ( transitionsFromCurrentStateRange.begin ( ), transitionsFromCurrentStateRange.end ( ) ); for ( const DefaultSymbolType & nonterminal : augmentedGrammar.getNonterminalAlphabet ( ) ) { ext::map < ext::pair<DefaultStateType, DefaultSymbolType >, DefaultStateType >::iterator transitionIterator = transitionsFromCurrentState.find ( { state, nonterminal } ); diff --git a/alib2data/src/automaton/FSM/DFA.h b/alib2data/src/automaton/FSM/DFA.h index cad8f15ae4a81833a53aaab4789ac6d3a82f5fef..48b0baa7965733747970da84050402d6c95899e4 100644 --- a/alib2data/src/automaton/FSM/DFA.h +++ b/alib2data/src/automaton/FSM/DFA.h @@ -338,7 +338,7 @@ public: * * \returns a subset of the transition function of the automaton with the source state fixed */ - ext::range < typename ext::map < ext::pair < StateType, SymbolType >, StateType >::const_iterator > getTransitionsFromState ( const StateType & from ) const; + ext::iterator_range < typename ext::map < ext::pair < StateType, SymbolType >, StateType >::const_iterator > getTransitionsFromState ( const StateType & from ) const; /** * Get the transition function of the automaton, with the target state fixed in the transitions natural representation. @@ -481,14 +481,14 @@ public: }; template<class SymbolType, class StateType > -ext::range < typename ext::map < ext::pair < StateType, SymbolType >, StateType >::const_iterator > DFA<SymbolType, StateType>::getTransitionsFromState ( const StateType & from ) const { +ext::iterator_range < typename ext::map < ext::pair < StateType, SymbolType >, StateType >::const_iterator > DFA<SymbolType, StateType>::getTransitionsFromState ( const StateType & from ) const { if ( !getStates ( ).count ( from ) ) throw AutomatonException ( "State \"" + ext::to_string ( from ) + "\" doesn't exist" ); auto lower = transitions.lower_bound ( Compar < SymbolType, StateType > ( from ) ); auto upper = transitions.upper_bound ( Compar < SymbolType, StateType > ( from ) ); - return ext::make_range ( lower, upper ); + return ext::make_iterator_range ( lower, upper ); } template<class SymbolType, class StateType > diff --git a/alib2std/src/extensions/range.hpp b/alib2std/src/extensions/range.hpp index bf1ba8204e3880933a1a64eab8ef30531c6ab854..0358089bf8e4556b2f0977d88fd4b6e14be36636 100644 --- a/alib2std/src/extensions/range.hpp +++ b/alib2std/src/extensions/range.hpp @@ -1,5 +1,5 @@ /* - * range.hpp as proposed http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3350.html by Jeffrey Yasskin <jyasskin@google.com> + * iterator_range.hpp as proposed http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3350.html by Jeffrey Yasskin <jyasskin@google.com> * * Created on: May 28, 2015 * Author: Jan Travnicek @@ -9,18 +9,18 @@ #define __RANGE_HPP_ #include <utility> -#include <iterator> +#include "iterator.hpp" namespace ext { /** * \brief - * Implementation of range, i.e. pair of iterators. The class provides most notably begin and end methods to allow the class be used in foreach context. + * Implementation of iterator_range, i.e. pair of iterators. The class provides most notably begin and end methods to allow the class be used in foreach context. * * \tparam Iterator the type of wrapped pair of iterators */ template<typename Iterator> -class range { +class iterator_range { /** * \brief * The begin iterator @@ -65,19 +65,19 @@ public: /** * \brief - * Constructor of empty range. Both iterators are initialized to default (same) value. + * Constructor of empty iterator_range. Both iterators are initialized to default (same) value. */ - range ( ) { + iterator_range ( ) { } /** * \brief - * Constructor to make range from pair of iterators + * Constructor to make iterator_range from pair of iterators * - * \param begin the begining of the wrapped range - * \param end the end of the wrapped range + * \param begin the begining of the wrapped iterator_range + * \param end the end of the wrapped iterator_range */ - constexpr range(Iterator begin, Iterator end) : m_begin ( begin ), m_end ( end ) { + constexpr iterator_range(Iterator begin, Iterator end) : m_begin ( begin ), m_end ( end ) { } /** @@ -102,7 +102,7 @@ public: /** * \brief - * Getter of the first value in the range. + * Getter of the first value in the iterator_range. * * \return reference to the first value */ @@ -112,7 +112,7 @@ public: /** * \brief - * Getter of the last value in the range. + * Getter of the last value in the iterator_range. * * \return reference to the last value */ @@ -132,9 +132,9 @@ public: /** * \brief - * Test whether the range is empty. + * Test whether the iterator_range is empty. * - * \return true of the two iterators representing range are equal. + * \return true of the two iterators representing iterator_range are equal. */ constexpr bool empty() const { return m_begin == m_end; @@ -184,82 +184,94 @@ public: /** * \brief - * Creates two sub ranges based on middle position. The element at the middle position is included in the second range. + * Creates two sub ranges based on middle position. The element at the middle position is included in the second iterator_range. * - * \param index the place where to cut the range in two + * \param index the place where to cut the iterator_range in two * * \return two subranges */ - std::pair< range, range > split(difference_type index) const { + std::pair< iterator_range, iterator_range > split(difference_type index) const { return std::make_pair ( slice ( 0, index ), slice ( index, 0 ) ); } /** * \brief - * Creates a subrange of the range representing interaval of values from \p start to \p stop. + * Creates a subrange of the iterator_range representing interaval of values from \p start to \p stop. * - * If the \p start is positive or zero, the actual cut position is calcuated relative to the begining of the range. - * If the \p start is negative, the actual cut position is calculated relative to the end of the range. + * If the \p start is positive or zero, the actual cut position is calcuated relative to the begining of the iterator_range. + * If the \p start is negative, the actual cut position is calculated relative to the end of the iterator_range. * - * If the \p end is positive, the actual cut position is calcuated relative to the begining of the range. - * If the \p start is negative or zero, the actual cut position is calculated relative to the end of the range. + * If the \p end is positive, the actual cut position is calcuated relative to the begining of the iterator_range. + * If the \p start is negative or zero, the actual cut position is calculated relative to the end of the iterator_range. * - * Example range ( 0, 1, 2, 3, 4, 5 ).slice ( 1, 3 ) produces range ( 1, 2 ); - * Example range ( 0, 1, 2, 3, 4, 5 ).slice ( -4, -1 ) produces range ( 2, 3, 4 ); + * Example iterator_range ( 0, 1, 2, 3, 4, 5 ).slice ( 1, 3 ) produces iterator_range ( 1, 2 ); + * Example iterator_range ( 0, 1, 2, 3, 4, 5 ).slice ( -4, -1 ) produces iterator_range ( 2, 3, 4 ); * * \param start the begin position of the resulting subrange * \param end the end position of the resulting subrange * - * \return subrange of the range. + * \return subrange of the iterator_range. */ - range slice(difference_type start, difference_type stop) const { - return range ( ( start >= 0 ? m_begin : m_end ) + start, ( stop > 0 ? m_begin : m_end ) + stop ); + iterator_range slice(difference_type start, difference_type stop) const { + return iterator_range ( ( start >= 0 ? m_begin : m_end ) + start, ( stop > 0 ? m_begin : m_end ) + stop ); } /** * \brief - * Creates a subrange of the range representing interaval of values from \p start to the end of the range. + * Creates a subrange of the iterator_range representing interaval of values from \p start to the end of the iterator_range. * - * If the \p start is positive or zero, the actual cut position is calcuated relative to the begining of the range. - * If the \p start is negative, the actual cut position is calculated relative to the end of the range. + * If the \p start is positive or zero, the actual cut position is calcuated relative to the begining of the iterator_range. + * If the \p start is negative, the actual cut position is calculated relative to the end of the iterator_range. * * The call is equivalent to slice ( begin, 0 ). * - * Example range ( 0, 1, 2, 3, 4, 5 ).slice ( 1 ) produces range ( 1, 2, 3, 4, 5 ); - * Example range ( 0, 1, 2, 3, 4, 5 ).slice ( -4 ) produces range ( 2, 3, 4, 5 ); + * Example iterator_range ( 0, 1, 2, 3, 4, 5 ).slice ( 1 ) produces iterator_range ( 1, 2, 3, 4, 5 ); + * Example iterator_range ( 0, 1, 2, 3, 4, 5 ).slice ( -4 ) produces iterator_range ( 2, 3, 4, 5 ); * * \param start the begin position of the resulting subrange * - * \return subrange of the range. + * \return subrange of the iterator_range. */ - range slice(difference_type start) const { + iterator_range slice(difference_type start) const { return slice ( start, 0 ); } }; /** * \brief - * Helper to create range from two iterators. + * Helper to create iterator_range from two iterators. * - * \return the range instance from two iterators + * \return the iterator_range instance from two iterators */ template < typename Iter > -range < Iter > make_range ( Iter begin, Iter end ) { - return range < Iter > ( begin, end ); +iterator_range < Iter > make_iterator_range ( Iter begin, Iter end ) { + return iterator_range < Iter > ( begin, end ); } /** - * \brief - * Helper to create range from two iterators. + * Generalization of range for universaly referenced containers. + * + * \param cont the container to call end on * - * \return the range instance from two iterators + * \result the range over all elements of the array */ -template < typename Container > -auto make_range ( Container && container ) { - return make_range ( std::forward < Container > ( container ).begin ( ), std::forward < Container > ( container ).end ( ) ); +template <class Container> +auto range ( Container && cont ) -> decltype ( std::forward < Container > ( cont ).range ( ) ) { + return ext::make_iterator_range ( std::forward < Container > ( cont ).begin ( ), std::forward < Container > ( cont ).end ( ) ); +} + +/** + * Specialization of range for static array. + * + * \param arr the static array + * + * \result the range over all elements of the array + */ +template < class T, size_t N > +constexpr ext::iterator_range < T * > range ( T ( & arr ) [ N ] ) noexcept { + return ext::make_iterator_range ( begin ( arr ), end ( arr ) ); } } /* namespace ext */ #endif /* __RANGE_HPP_ */ - diff --git a/alib2std/test-src/extensions/RangeTest.cpp b/alib2std/test-src/extensions/RangeTest.cpp index 37986689284d1faa5fbc7db8ea4f4ac394409d87..a9f5182e66524da59669974f86049fb084ee72a1 100644 --- a/alib2std/test-src/extensions/RangeTest.cpp +++ b/alib2std/test-src/extensions/RangeTest.cpp @@ -15,15 +15,15 @@ void RangeTest::tearDown ( ) { void RangeTest::constructorTest ( ) { int arr[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - ext::range < int * > ra1 ( arr, arr + sizeof ( arr ) / sizeof ( * arr ) ); + ext::iterator_range < int * > ra1 = ext::range ( arr ); ext::vector < int > v1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - ext::range < ext::vector < int >::iterator > rv1 ( v1.begin ( ), v1.end ( ) ); + ext::iterator_range < ext::vector < int >::iterator > rv1 ( v1.begin ( ), v1.end ( ) ); CPPUNIT_ASSERT ( ( std::equal ( ra1.begin ( ), ra1.end ( ), rv1.begin ( ), rv1.end ( ) ) ) ); - auto rv2 = ext::make_range ( v1 ); + auto rv2 = ext::range ( v1 ); CPPUNIT_ASSERT ( ( std::equal ( rv1.begin ( ), rv1.end ( ), rv2.begin ( ), rv2.end ( ) ) ) ); } @@ -31,19 +31,19 @@ void RangeTest::constructorTest ( ) { void RangeTest::sizeTest ( ) { int arr[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - ext::range < int * > ra1 ( arr, arr + sizeof ( arr ) / sizeof ( * arr ) ); + ext::iterator_range < int * > ra1 ( arr, arr + sizeof ( arr ) / sizeof ( * arr ) ); CPPUNIT_ASSERT ( ra1.size ( ) == 10 ); ext::vector < int > v1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - ext::range < ext::vector < int >::iterator > rv1 ( v1.begin ( ), v1.end ( ) ); + ext::iterator_range < ext::vector < int >::iterator > rv1 ( v1.begin ( ), v1.end ( ) ); CPPUNIT_ASSERT ( rv1.size ( ) == 10 ); ext::list < int > l1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - ext::range < ext::list < int >::iterator > rl1 ( l1.begin ( ), l1.end ( ) ); + ext::iterator_range < ext::list < int >::iterator > rl1 ( l1.begin ( ), l1.end ( ) ); CPPUNIT_ASSERT ( rl1.size ( ) == 10 ); } @@ -51,15 +51,15 @@ void RangeTest::sizeTest ( ) { void RangeTest::splitTest ( ) { ext::vector < int > v1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - auto r1 = ext::make_range ( v1 ); + auto r1 = ext::range ( v1 ); ext::vector < int > v2 = { 0, 1, 2 }; - auto r2 = ext::make_range ( v2 ); + auto r2 = ext::range ( v2 ); ext::vector < int > v3 = { 3, 4, 5, 6, 7, 8, 9 }; - auto r3 = ext::make_range ( v3 ); + auto r3 = ext::range ( v3 ); auto splitted = r1.split ( 3 ); @@ -70,11 +70,11 @@ void RangeTest::splitTest ( ) { void RangeTest::sliceTest ( ) { ext::vector < int > v1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - auto r1 = ext::make_range ( v1 ); + auto r1 = ext::range ( v1 ); ext::vector < int > v2 = { 4, 5, 6 }; - auto r2 = ext::make_range ( v2 ); + auto r2 = ext::range ( v2 ); auto sliced = r1.slice ( 4, -3 ); diff --git a/alib2str/src/automaton/string/FSM/DFA.h b/alib2str/src/automaton/string/FSM/DFA.h index c9b0f48c6b607053d0e75828d20773fb02bf12dd..88f4a60f5caa2f6939aabbab99fc720e43a3f46c 100644 --- a/alib2str/src/automaton/string/FSM/DFA.h +++ b/alib2str/src/automaton/string/FSM/DFA.h @@ -156,7 +156,7 @@ void stringApi < automaton::DFA < SymbolType, StateType > >::compose ( std::ostr template < class SymbolType, class StateType > void stringApi < automaton::DFA < SymbolType, StateType > >::composeTransitionsFromState(std::ostream& output, const automaton::DFA < SymbolType, StateType > & automaton, const StateType & from) { - ext::range < typename ext::map < ext::pair < StateType, SymbolType >, StateType >::const_iterator > symbolTransitionsFromState = automaton.getTransitionsFromState(from); + ext::iterator_range < typename ext::map < ext::pair < StateType, SymbolType >, StateType >::const_iterator > symbolTransitionsFromState = automaton.getTransitionsFromState(from); for(const SymbolType& inputSymbol : automaton.getInputAlphabet()) { if ( ! symbolTransitionsFromState.empty ( ) && symbolTransitionsFromState.front ( ).first.second == inputSymbol ) {