Merge "Prepare for Tizen 4.0 Build" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / builder / dictionary.h
1 #ifndef DALI_TOOLKIT_INTERNAL_BUILDER_DICTIONARY_H
2 #define DALI_TOOLKIT_INTERNAL_BUILDER_DICTIONARY_H
3
4 /*
5  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 #include <dali/public-api/common/vector-wrapper.h>
21 #include <algorithm>
22
23 namespace Dali
24 {
25 extern bool CaseInsensitiveStringCompare( const std::string& a, const std::string& b );
26
27 namespace Toolkit
28 {
29 namespace Internal
30 {
31
32 /**
33  * The Dictionary template class enables a means of storing key-value
34  * pairs where the keys are strings and the value can be a complex
35  * type.
36  *
37  * It enables lookup of keys via case-insensitive match.
38  */
39 template<typename EntryType>
40 class Dictionary
41 {
42 private:
43   /**
44    * Element is a key-value pair
45    */
46   struct Element
47   {
48     std::string key;
49     EntryType entry;
50     Element( const std::string&name, EntryType entry )
51     : key( name ),
52       entry( entry )
53     {
54     }
55   };
56   typedef std::vector<Element> Elements;
57   Elements container;
58
59 public:
60   /**
61    * Only allow const iteration over the dictionary
62    */
63   typedef typename Elements::const_iterator iterator;
64
65
66   /**
67    * Constructor
68    */
69   Dictionary<EntryType>()
70   {
71   }
72
73   /**
74    * Add a key value pair to the dictionary.
75    * If the entry does not already exist, add it to the dictionary
76    * using a shallow copy
77    */
78   bool Add( const std::string& name, const EntryType& entry )
79   {
80     for( typename Elements::iterator iter = container.begin(); iter != container.end(); ++iter )
81     {
82       if( iter->key == name )
83       {
84         return false;
85       }
86     }
87     container.push_back( Element(name, entry) );
88     return true;
89   }
90
91   /**
92    * Add a key-value pair to the dictionary
93    * If the entry does not already exist, add it to the dictionary
94    * (shallow copy)
95    */
96   bool Add( const char* name, const EntryType& entry )
97   {
98     bool result=false;
99     if( name != NULL )
100     {
101       std::string theName(name);
102       result=Add(theName, entry);
103     }
104     return result;
105   }
106
107   /**
108    * Find the element in the dictionary pointed at by key, and
109    * return a pointer to it, or NULL.
110    */
111   EntryType* Find( const std::string& key ) const
112   {
113     EntryType* result=NULL;
114
115     if( ! key.empty() )
116     {
117       for( typename Elements::iterator iter = container.begin(); iter != container.end(); ++iter )
118       {
119         if( iter->key == key )
120         {
121           result = &(iter->entry);
122           break;
123         }
124       }
125     }
126     return result;
127   }
128
129   /**
130    * Find the element in the dictionary pointed at by key, and
131    * return a pointer to it, or NULL
132    */
133   EntryType* Find( const char* key ) const
134   {
135     if( key != NULL )
136     {
137       std::string theKey(key);
138       return Find(theKey);
139     }
140     return NULL;
141   }
142
143   /**
144    * Find the element in the dictionary pointed at by key using a case
145    * insensitive search, and return a const pointer to it, or NULL
146    */
147   const EntryType* FindCaseInsensitiveC( const std::string& key ) const
148   {
149     if( ! key.empty() )
150     {
151       for( typename Elements::const_iterator iter = container.begin(); iter != container.end(); ++iter )
152       {
153         if( Dali::CaseInsensitiveStringCompare(iter->key, key ))
154         {
155           const EntryType* result = &(iter->entry);
156           return result;
157         }
158       }
159     }
160     return NULL;
161   }
162
163   /**
164    * Find the element in the dictionary pointed at by key using a case
165    * insensitive search, and return a non-const pointer to it, or NULL
166    */
167   EntryType* FindCaseInsensitive( const std::string& key ) const
168   {
169     EntryType* result = NULL;
170     if( ! key.empty() )
171     {
172       for( typename Elements::const_iterator iter = container.begin(); iter != container.end(); ++iter )
173       {
174         if( Dali::CaseInsensitiveStringCompare(iter->key, key ))
175         {
176           // Const cast because of const_iterator. const_iterator because, STL.
177           result = const_cast<EntryType*>(&(iter->entry));
178         }
179       }
180     }
181     return result;
182   }
183
184   /**
185    * Find the element in the dictionary pointed at by key using a case
186    * insensitive search, and return a const pointer to it, or NULL
187    */
188   const EntryType* FindCaseInsensitiveC( const char* key ) const
189   {
190     if( key != NULL )
191     {
192       std::string theKey(key);
193       return FindCaseInsensitiveC( theKey );
194     }
195     return NULL;
196   }
197
198   /**
199    * Find the element in the dictionary pointed at by key using a case
200    * insensitive search, and return a non-const pointer to it, or NULL
201    */
202   EntryType* FindCaseInsensitive( const char* key ) const
203   {
204     if( key != NULL )
205     {
206       std::string theKey(key);
207       return FindCaseInsensitive( theKey );
208     }
209     return NULL;
210   }
211
212   /**
213    * Return an iterator pointing at the first entry in the dictionary
214    */
215   typename Elements::const_iterator Begin() const
216   {
217     return container.begin();
218   }
219
220   /**
221    * Return an iterator pointing past the last entry in the dictionary
222    */
223   typename Elements::const_iterator End() const
224   {
225     return container.end();
226   }
227 };
228
229
230
231 }//Internal
232 }//Toolkit
233 }//Dali
234
235 #endif // DALI_TOOLKIT_INTERNAL_BUILDER_DICTIONARY_H