1 /*
2  * pair.h -- definition of the pair of scanners
3  *
4  * Copyright (c) 2007-2010, Dmitry Prokoptsev <dprokoptsev@gmail.com>,
5  *                          Alexander Gololobov <agololobov@gmail.com>
6  *
7  * This file is part of Pire, the Perl Incompatible
8  * Regular Expressions library.
9  *
10  * Pire is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU Lesser Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * Pire is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser Public License for more details.
19  * You should have received a copy of the GNU Lesser Public License
20  * along with Pire.  If not, see <http://www.gnu.org/licenses>.
21  */
22 
23 #ifndef PIRE_SCANNER_PAIR_INCLUDED
24 #define PIRE_SCANNER_PAIR_INCLUDED
25 
26 namespace Pire {
27 
28         /**
29          * A pair of scanner, providing the interface of a scanner itself.
30          * If you need to run two scanners on the same string, using ScannerPair
31          * is usually faster then running those scanners sequentially.
32          */
33 	template<class Scanner1, class Scanner2>
34 	class ScannerPair {
35 	public:
36 		typedef ypair<typename Scanner1::State, typename Scanner2::State> State;
37 		typedef ypair<typename Scanner1::Action, typename Scanner2::Action> Action;
38 
ScannerPair()39 		ScannerPair()
40 			: m_scanner1()
41 			, m_scanner2()
42 		{
43 		}
ScannerPair(const Scanner1 & s1,const Scanner2 & s2)44 		ScannerPair(const Scanner1& s1, const Scanner2& s2)
45 			: m_scanner1(&s1)
46 			, m_scanner2(&s2)
47 		{
48 		}
49 
Initialize(State & state)50 		void Initialize(State& state) const
51 		{
52 			m_scanner1->Initialize(state.first);
53 			m_scanner2->Initialize(state.second);
54 		}
55 
Next(State & state,Char ch)56 		Action Next(State& state, Char ch) const
57 		{
58 			return ymake_pair(
59 				m_scanner1->Next(state.first, ch),
60 				m_scanner2->Next(state.second, ch)
61 			);
62 		}
63 
TakeAction(State & s,Action a)64 		void TakeAction(State& s, Action a) const
65 		{
66 			m_scanner1->TakeAction(s.first, a.first);
67 			m_scanner2->TakeAction(s.second, a.second);
68 		}
69 
Final(const State & state)70 		bool Final(const State& state) const
71 		{
72 			return m_scanner1->Final(state.first) || m_scanner2->Final(state.second);
73 		}
74 
Dead(const State & state)75 		bool Dead(const State& state) const
76 		{
77 			return m_scanner1->Dead(state.first) && m_scanner2->Dead(state.second);
78 		}
79 
StateIndex(const State & state)80 		ypair<size_t, size_t> StateIndex(const State& state) const
81 		{
82 			return ymake_pair(m_scanner1->StateIndex(state.first), m_scanner2->StateIndex(state.second));
83 		}
84 
First()85 		Scanner1& First() { return *m_scanner1; }
Second()86 		Scanner2& Second() { return *m_scanner2; }
87 
First()88 		const Scanner1& First() const { return *m_scanner1; }
Second()89 		const Scanner2& Second() const { return *m_scanner2; }
90 
91 	private:
92 		const Scanner1* m_scanner1;
93 		const Scanner2* m_scanner2;
94 	};
95 
96 
97 }
98 
99 #endif
100