Improve the process for GNU tools
[minix3.git] / external / bsd / kyua-cli / dist / utils / config / nodes.ipp
blob7296ed56fc45594aed81902f1f82c8f627b986e4
1 // Copyright 2012 Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 //   notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 //   notice, this list of conditions and the following disclaimer in the
12 //   documentation and/or other materials provided with the distribution.
13 // * Neither the name of Google Inc. nor the names of its contributors
14 //   may be used to endorse or promote products derived from this software
15 //   without specific prior written permission.
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include "utils/config/nodes.hpp"
31 #if !defined(UTILS_CONFIG_NODES_IPP)
32 #define UTILS_CONFIG_NODES_IPP
34 #include <memory>
35 #include <typeinfo>
37 #include "utils/config/exceptions.hpp"
38 #include "utils/defs.hpp"
39 #include "utils/format/macros.hpp"
40 #include "utils/optional.ipp"
41 #include "utils/text/exceptions.hpp"
42 #include "utils/text/operations.ipp"
43 #include "utils/sanity.hpp"
45 namespace utils {
48 namespace config {
49 namespace detail {
52 /// Type of the new_node() family of functions.
53 typedef base_node* (*new_node_hook)(void);
56 /// Creates a new leaf node of a given type.
57 ///
58 /// \tparam NodeType The type of the leaf node to create.
59 ///
60 /// \return A pointer to the newly-created node.
61 template< class NodeType >
62 base_node*
63 new_node(void)
65     return new NodeType();
69 /// Internal node of the tree.
70 ///
71 /// This abstract base class provides the mechanism to implement both static and
72 /// dynamic nodes.  Ideally, the implementation would be split in subclasses and
73 /// this class would not include the knowledge of whether the node is dynamic or
74 /// not.  However, because the static/dynamic difference depends on the leaf
75 /// types, we need to declare template functions and these cannot be virtual.
76 class inner_node : public base_node {
77     /// Whether the node is dynamic or not.
78     bool _dynamic;
80 protected:
81     /// Type to represent the collection of children of this node.
82     ///
83     /// Note that these are one-level keys.  They cannot contain dots, and thus
84     /// is why we use a string rather than a tree_key.
85     typedef std::map< std::string, base_node* > children_map;
87     /// Mapping of keys to values that are descendants of this node.
88     children_map _children;
90     void copy_into(inner_node* new_node) const;
92 public:
93     inner_node(const bool);
94     virtual ~inner_node(void) = 0;
96     const base_node* lookup_ro(const tree_key&,
97                                const tree_key::size_type) const;
98     leaf_node* lookup_rw(const tree_key&, const tree_key::size_type,
99                          new_node_hook);
101     void all_properties(properties_map&, const tree_key&) const;
105 /// Static internal node of the tree.
107 /// The direct children of this node must be pre-defined by calls to define().
108 /// Attempts to traverse this node and resolve a key that is not a pre-defined
109 /// children will result in an "unknown key" error.
110 class static_inner_node : public config::detail::inner_node {
111 public:
112     static_inner_node(void);
114     virtual base_node* deep_copy(void) const;
116     void define(const tree_key&, const tree_key::size_type, new_node_hook);
120 /// Dynamic internal node of the tree.
122 /// The children of this node need not be pre-defined.  Attempts to traverse
123 /// this node and resolve a key will result in such key being created.  Any
124 /// intermediate non-existent nodes of the traversal will be created as dynamic
125 /// inner nodes as well.
126 class dynamic_inner_node : public config::detail::inner_node {
127 public:
128     virtual base_node* deep_copy(void) const;
130     dynamic_inner_node(void);
134 }  // namespace detail
135 }  // namespace config
138 /// Constructor for a node with an undefined value.
140 /// This should only be called by the tree's define() method as a way to
141 /// register a node as known but undefined.  The node will then serve as a
142 /// placeholder for future values.
143 template< typename ValueType >
144 config::typed_leaf_node< ValueType >::typed_leaf_node(void) :
145     _value(none)
150 /// Checks whether the node has been set.
152 /// Remember that a node can exist before holding a value (i.e. when the node
153 /// has been defined as "known" but not yet set by the user).  This function
154 /// checks whether the node laready holds a value.
156 /// \return True if a value has been set in the node.
157 template< typename ValueType >
158 bool
159 config::typed_leaf_node< ValueType >::is_set(void) const
161     return static_cast< bool >(_value);
165 /// Gets the value stored in the node.
167 /// \pre The node must have a value.
169 /// \return The value in the node.
170 template< typename ValueType >
171 const typename config::typed_leaf_node< ValueType >::value_type&
172 config::typed_leaf_node< ValueType >::value(void) const
174     PRE(is_set());
175     return _value.get();
179 /// Gets the read-write value stored in the node.
181 /// \pre The node must have a value.
183 /// \return The value in the node.
184 template< typename ValueType >
185 typename config::typed_leaf_node< ValueType >::value_type&
186 config::typed_leaf_node< ValueType >::value(void)
188     PRE(is_set());
189     return _value.get();
193 /// Sets the value of the node.
195 /// \param value_ The new value to set the node to.
197 /// \throw value_error If the value is invalid, according to validate().
198 template< typename ValueType >
199 void
200 config::typed_leaf_node< ValueType >::set(const value_type& value_)
202     validate(value_);
203     _value = optional< value_type >(value_);
207 /// Checks a given value for validity.
209 /// This is called internally by the node right before updating the recorded
210 /// value.  This method can be redefined by subclasses.
212 /// \param unused_new_value The value to validate.
214 /// \throw value_error If the value is not valid.
215 template< typename ValueType >
216 void
217 config::typed_leaf_node< ValueType >::validate(
218     const value_type& UTILS_UNUSED_PARAM(new_value)) const
223 /// Sets the value of the node from a raw string representation.
225 /// \param raw_value The value to set the node to.
227 /// \throw value_error If the value is invalid.
228 template< typename ValueType >
229 void
230 config::native_leaf_node< ValueType >::set_string(const std::string& raw_value)
232     try {
233         typed_leaf_node< ValueType >::set(text::to_type< ValueType >(
234             raw_value));
235     } catch (const text::value_error& e) {
236         throw config::value_error(F("Failed to convert string value '%s' to "
237                                     "the node's type") % raw_value);
238     }
242 /// Converts the contents of the node to a string.
244 /// \pre The node must have a value.
246 /// \return A string representation of the value held by the node.
247 template< typename ValueType >
248 std::string
249 config::native_leaf_node< ValueType >::to_string(void) const
251     PRE(typed_leaf_node< ValueType >::is_set());
252     return F("%s") % typed_leaf_node< ValueType >::value();
256 /// Constructor for a node with an undefined value.
258 /// This should only be called by the tree's define() method as a way to
259 /// register a node as known but undefined.  The node will then serve as a
260 /// placeholder for future values.
261 template< typename ValueType >
262 config::base_set_node< ValueType >::base_set_node(void) :
263     _value(none)
268 /// Checks whether the node has been set.
270 /// Remember that a node can exist before holding a value (i.e. when the node
271 /// has been defined as "known" but not yet set by the user).  This function
272 /// checks whether the node laready holds a value.
274 /// \return True if a value has been set in the node.
275 template< typename ValueType >
276 bool
277 config::base_set_node< ValueType >::is_set(void) const
279     return static_cast< bool >(_value);
283 /// Gets the value stored in the node.
285 /// \pre The node must have a value.
287 /// \return The value in the node.
288 template< typename ValueType >
289 const typename config::base_set_node< ValueType >::value_type&
290 config::base_set_node< ValueType >::value(void) const
292     PRE(is_set());
293     return _value.get();
297 /// Gets the read-write value stored in the node.
299 /// \pre The node must have a value.
301 /// \return The value in the node.
302 template< typename ValueType >
303 typename config::base_set_node< ValueType >::value_type&
304 config::base_set_node< ValueType >::value(void)
306     PRE(is_set());
307     return _value.get();
311 /// Sets the value of the node.
313 /// \param value_ The new value to set the node to.
315 /// \throw value_error If the value is invalid, according to validate().
316 template< typename ValueType >
317 void
318 config::base_set_node< ValueType >::set(const value_type& value_)
320     validate(value_);
321     _value = optional< value_type >(value_);
325 /// Sets the value of the node from a raw string representation.
327 /// \param raw_value The value to set the node to.
329 /// \throw value_error If the value is invalid.
330 template< typename ValueType >
331 void
332 config::base_set_node< ValueType >::set_string(const std::string& raw_value)
334     std::set< ValueType > new_value;
336     const std::vector< std::string > words = text::split(raw_value, ' ');
337     for (std::vector< std::string >::const_iterator iter = words.begin();
338          iter != words.end(); ++iter) {
339         if (!(*iter).empty())
340             new_value.insert(parse_one(*iter));
341     }
343     set(new_value);
347 /// Converts the contents of the node to a string.
349 /// \pre The node must have a value.
351 /// \return A string representation of the value held by the node.
352 template< typename ValueType >
353 std::string
354 config::base_set_node< ValueType >::to_string(void) const
356     PRE(is_set());
357     return text::join(_value.get(), " ");
361 /// Pushes the node's value onto the Lua stack.
363 /// \param unused_state The Lua state onto which to push the value.
364 template< typename ValueType >
365 void
366 config::base_set_node< ValueType >::push_lua(
367     lutok::state& UTILS_UNUSED_PARAM(state)) const
369     UNREACHABLE;
373 /// Sets the value of the node from an entry in the Lua stack.
375 /// \param unused_state The Lua state from which to get the value.
376 /// \param unused_value_index The stack index in which the value resides.
378 /// \throw value_error If the value in state(value_index) cannot be
379 ///     processed by this node.
380 template< typename ValueType >
381 void
382 config::base_set_node< ValueType >::set_lua(
383     lutok::state& UTILS_UNUSED_PARAM(state),
384     const int UTILS_UNUSED_PARAM(value_index))
386     UNREACHABLE;
390 /// Checks a given value for validity.
392 /// This is called internally by the node right before updating the recorded
393 /// value.  This method can be redefined by subclasses.
395 /// \param unused_new_value The value to validate.
397 /// \throw value_error If the value is not valid.
398 template< typename ValueType >
399 void
400 config::base_set_node< ValueType >::validate(
401     const value_type& UTILS_UNUSED_PARAM(new_value)) const
406 }  // namespace utils
408 #endif  // !defined(UTILS_CONFIG_NODES_IPP)