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