]> git.lyx.org Git - lyx.git/blob - src/support/translator.h
* src/encoding.C (latexChar,read):
[lyx.git] / src / support / translator.h
1 // -*- C++ -*-
2 /**
3  * \file translator.h
4  * This file is part of LyX, the document processor.
5  * Licence details can be found in the file COPYING.
6  *
7  * \author Baruch Even
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #ifndef TRANSLATOR_H
13 #define TRANSLATOR_H
14
15 #include <boost/assert.hpp>
16 #include <boost/bind.hpp>
17
18 #include <vector>
19 #include <utility>
20 #include <algorithm>
21 #include <functional>
22
23
24 namespace lyx {
25
26 /**
27  * This class template is used to translate between two elements, specifically
28  * it was worked out to translate between an enum and strings when reading
29  * the lyx file.
30  *
31  * The two template arguments should be of different types.
32  */
33 template<typename T1, typename T2>
34 class Translator {
35 public:
36         ///
37         typedef T1 first_argument_type;
38         ///
39         typedef T2 second_argument_type;
40         ///
41         typedef std::pair<T1, T2> MapPair;
42         ///
43         typedef std::vector<MapPair> Map;
44
45         ///
46         Translator(T1 const & t1, T2 const & t2)
47                 : default_t1(t1), default_t2(t2)
48                 {}
49
50         /// Add a mapping to the translator.
51         void addPair(T1 const & first, T2 const & second) {
52                 map.push_back(MapPair(first, second));
53         }
54         // Add the contents of \c other
55         void add(Translator const & other) {
56                 if (other.map.empty())
57                         return;
58                 map.insert(map.end(), other.map.begin(), other.map.end());
59         }
60
61         /// Find the mapping for the first argument
62         T2 const & find(T1 const & first) const {
63                 BOOST_ASSERT(!map.empty());
64
65                 // For explanation see the next find() function.
66                 typename Map::const_iterator it =
67                         std::find_if(map.begin(), map.end(),
68                                      boost::bind(std::equal_to<T1>(),
69                                                  boost::bind(&MapPair::first, _1),
70                                                  first)
71                                 );
72
73                 if (it != map.end()) {
74                         return it->second;
75                 } else {
76                         return default_t2;
77                 }
78         }
79
80         /// Find the mapping for the second argument
81         T1 const & find(T2 const & second) const {
82                 BOOST_ASSERT(!map.empty());
83
84                 // The idea is as follows:
85                 // find_if() will try to compare the data in the vector with
86                 // the value. The vector is made of pairs and the value has
87                 // the type of the second part of the pair.
88                 // We thus give find_if() an equal_to functor and assign to
89                 // its second post the value we want to compare. We now
90                 // compose the equal_to functor with the select2nd functor
91                 // to take only the second value of the pair to be compared.
92                 //
93                 // We can depict it as follows:
94                 // equal_to(select2nd(pair) , second)
95                 typename Map::const_iterator it =
96                         std::find_if(map.begin(), map.end(),
97                                      boost::bind(std::equal_to<T2>(),
98                                                  boost::bind(&MapPair::second, _1),
99                                                  second)
100                                 );
101
102                 if (it != map.end())
103                         return it->first;
104                 else {
105                         return default_t1;
106                 }
107         }
108 private:
109         ///
110         Map map;
111         ///
112         T1 const default_t1;
113         ///
114         T2 const default_t2;
115 };
116
117
118 } // namespace lyx
119
120 #endif // TRANSLATOR_H