• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

TsValue.h

Go to the documentation of this file.
00001 # if ! defined(TS_CONFIG_VALUE_HEADER)
00002 # define TS_CONFIG_VALUE_HEADER
00003 
00004 /** @file
00005 
00006     TS Configuration API definition.
00007 
00008     @section license License
00009 
00010     Licensed to the Apache Software Foundation (ASF) under one
00011     or more contributor license agreements.  See the NOTICE file
00012     distributed with this work for additional information
00013     regarding copyright ownership.  The ASF licenses this file
00014     to you under the Apache License, Version 2.0 (the
00015     "License"); you may not use this file except in compliance
00016     with the License.  You may obtain a copy of the License at
00017 
00018     http://www.apache.org/licenses/LICENSE-2.0
00019 
00020     Unless required by applicable law or agreed to in writing, software
00021     distributed under the License is distributed on an "AS IS" BASIS,
00022     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00023     See the License for the specific language governing permissions and
00024     limitations under the License.
00025  */
00026 
00027 # include <string.h>
00028 # include <ts/TsBuffer.h>
00029 # include <tsconfig/NumericType.h>
00030 # include <tsconfig/IntrusivePtr.h>
00031 # include <tsconfig/Errata.h>
00032 # include <vector>
00033 
00034 namespace ts { namespace config {
00035 
00036 // Forward declares.
00037 class Value;
00038 class Path;
00039 
00040 namespace detail {
00041   /** Class to provide a "pseudo bool" value.
00042       This is used as the return type for the positive logical operator
00043       (the converse of @c operator! ). This makes a class directly
00044       usable in logical expressions. It is like a pointer but @b not
00045       convertible to anything else, and so avoiding any undesirable
00046       automatic conversions and the resulting ambiguities.
00047   */
00048   struct PseudoBool {
00049     typedef bool (PseudoBool::*Type)() const; ///< The type itself.
00050     bool operator ! () const; ///< A method to use for the @c true value.
00051     static Type const TRUE; ///< The @c true equivalent.
00052     static Type const FALSE; ///< The @c false equivalent.
00053   };
00054 }
00055 
00056 /// Type of value.
00057 enum ValueType {
00058   VoidValue, ///< No value, invalid.
00059   ListValue, ///< List of values.
00060   GroupValue, ///< Group of values.
00061   StringValue, ///< Text string.
00062   IntegerValue, ///< Integer.
00063   PathValue, ///< Path.
00064   // Update N_VALUE_TYPES if you change the last enum value !!
00065 };
00066 /// Number of value types.
00067 static size_t const N_VALUE_TYPES = PathValue + 1;
00068 
00069 /** A path to a value in a configuration.
00070  */
00071 class Path {
00072   friend class Value;
00073 protected:
00074   class ImplType : public IntrusivePtrCounter {
00075     friend class Path;
00076   public:
00077     ImplType(); ///< Constructor.
00078   protected:
00079     /** Container for path elements.
00080         We are subtle with our elements, which can be either a string
00081         or a numeric index. By convention, if the pointer in the buffer is
00082         @c NULL, then the size is a numeric index. Otherwise it's a name.
00083     */
00084     typedef std::vector<ConstBuffer> Elements;
00085     Elements _elements; ///< Path elements.
00086   };
00087 public:
00088   typedef Path self; ///< Self reference type.
00089 
00090   Path(); ///< Default constructor.
00091 
00092   /// Append a string tag to the path.
00093   self& append(
00094     ConstBuffer const& tag ///< Text of tag.
00095   );
00096   /// Append a numeric index to the path.
00097   self& append(
00098     size_t idx ///< Index.
00099   );
00100   /// Reset to default constructed state.
00101   self& reset();
00102 
00103   /// Get the number of elements in this path.
00104   size_t count() const;
00105 
00106   /// Access an element by @a index.
00107   ConstBuffer const& operator [] (
00108     size_t index ///< Element index.
00109   ) const;
00110 
00111   /** Parser for path text.
00112       This is restartable so a path can be parsed in pieces.
00113       @internal Sadly, FLEX is just too much overhead to be useful here.
00114   */
00115   class Parser {
00116   public:
00117     typedef Parser self; ///< Self reference type.
00118 
00119     Parser(); ///< Default constructor.
00120     /** Construct with input.
00121 
00122         This default constructs the Parser then calls @c setInput with
00123         @a text. It is provided as a convenience as that will be the
00124         common use case.
00125 
00126         @see setInput.
00127     */
00128     Parser(
00129       ConstBuffer const& text ///< Input text.
00130     );
00131 
00132     /** Set the input @a text.
00133         Parsing state is reset and the next parsing call will
00134         start at the beginning of @a text.
00135     */
00136     self& setInput(
00137       ConstBuffer const& text ///< Input buffer.
00138     );
00139 
00140     /// Parsing result.
00141     enum Result {
00142       ERROR, ///< Bad input.
00143       TAG, ///< Path tag.
00144       INDEX, ///< Path index.
00145       EOP, ///< End Of Path.
00146     };
00147 
00148     /** Parse the next element in the path.
00149 
00150         @a cbuff may be @c NULL in which case no data about elements
00151         is available.  In general this should be called until @c EOP
00152         or @c ERROR is returned, each call returning the next element.
00153 
00154         @return A parse @c Result.
00155         - TAG: A tag was found. The start and length are stored in @a cbuff.
00156         - INDEX: An index was found. The value is in @a cbuff._size.
00157         - EOP: No more path elements were found. Do not continue parsing.
00158         - ERROR: A syntax error was encountered. See the errata for detail. Do not continue parsing.
00159     */
00160     Rv<Result> parse(
00161       ConstBuffer* cbuff = 0 ///< [out] Parsed path element.
00162     );
00163 
00164     /// Check if input is available.
00165     bool hasInput() const;
00166 
00167   protected:
00168     ConstBuffer _input; ///< Current input buffer.
00169     char const* _c; ///< Next input character.
00170   };
00171 protected:
00172   typedef IntrusivePtr<ImplType> ImplPtr; ///< Smart pointer to implementation.
00173   ImplPtr _ptr; ///< Our instance.
00174   /// Force an implementation instance and return a pointer to it.
00175   ImplType* instance();
00176 };
00177 
00178 namespace detail {
00179   /// Null buffer, handy in several places.
00180   extern Buffer const NULL_BUFFER;
00181   /// Null buffer, handy in several places.
00182   extern ConstBuffer const NULL_CONST_BUFFER;
00183   /// Index type for value items in the global table.
00184   typedef NumericType<size_t, struct ValueIndexTag> ValueIndex;
00185   /// Index value that presents NULL (invalid value).
00186   static ValueIndex const NULL_VALUE_INDEX = static_cast<ValueIndex::raw_type>(-1);
00187   /// Numeric type for configuration generation.
00188   typedef NumericType<size_t, struct GenerationTag> Generation;
00189 
00190   /** Value type properties.
00191       These are used as bit masks on elements of an array.
00192   */
00193   static unsigned int const IS_VALID = 1;
00194   static unsigned int const IS_LITERAL = 1<<1;
00195   static unsigned int const IS_CONTAINER = 1<<2;
00196 
00197   /// Value type property table.
00198   extern unsigned int const Type_Property[N_VALUE_TYPES];
00199 
00200   /** A value in the configuration.
00201       This is used in a global table so it handles all types of Values.
00202       Members that are not used for scalars are designed to be @c NULL
00203       pointers in that case.
00204   */
00205   class ValueItem {
00206     // Apparently the C++ standard, 7.3.1.2, states that unqualified
00207     // friend classes only considers the current namespace, not any
00208     // outer ones. So we have to fully qualify this. Blech.
00209     friend class ts::config::Value;
00210     friend class ValueTable;
00211   public:
00212     /// Default constructor.
00213     ValueItem();
00214     /// Construct empty item of a specific type.
00215     ValueItem(ValueType type);
00216     /// Get item type.
00217     ValueType getType() const;
00218   protected:
00219     ValueType _type;      ///< Type of value.
00220     ValueIndex _parent;   ///< Table index of parent value.
00221     ConstBuffer _text;    ///< Text of value (if scalar).
00222     ConstBuffer _name;    ///< Local name of value, if available.
00223     size_t _local_index;  ///< Index among siblings.
00224     int _srcLine;         ///< Source line.
00225     int _srcColumn;       ///< Source column.
00226 
00227     /// Container for children of this item.
00228     typedef std::vector<ValueIndex> ChildGroup;
00229     /// Child items of this item.
00230     ChildGroup _children;
00231     /// Path if present.
00232     Path _path;
00233 
00234     // This is for optimizing named access at some point in the future.
00235     /// Hold a child item name in a table for fast lookup.
00236     struct Name {
00237       ConstBuffer _text; ///< Text of name.
00238       ValueIndex _index; ///< Index of child.
00239     };
00240     /// Container for child names.
00241     typedef std::vector<Name> NameGroup;
00242     /** Child names, if appropriate.
00243         This is faulted in when needed, if this value is an aggregate with
00244         named children. The list must be sorted on name so that it can be binary
00245         searched for performance.
00246     */
00247     NameGroup _names;
00248   };
00249 
00250   class ValueTable;
00251 
00252   /** Table of configuration values.
00253       This holds all the values for a specific configuration.
00254   */
00255   class ValueTableImpl : public IntrusivePtrCounter {
00256     friend class ValueTable;
00257   public:
00258     typedef ValueTableImpl self; ///< Self reference type.
00259 
00260     ValueTableImpl(); ///< Constructor.
00261     ~ValueTableImpl(); ///< Destructor.
00262   protected:
00263     /// Container for value items.
00264     typedef std::vector<ValueItem> ItemTable;
00265     ItemTable _values; ///< All configuration values.
00266     Generation _generation; ///< Generation number of configuration.
00267     /// A group of buffers.
00268     typedef std::vector<Buffer> BufferGroup;
00269     /** Locally allocated buffers.
00270         These are freed when this object is destroyed.
00271     */
00272     BufferGroup _buffers;
00273 
00274     static ValueItem NULL_ITEM; ///< Null item for invalid access return.
00275   };
00276 
00277   /** Wrapper class for a table of configuration values.
00278       @internal Really, this should be merged in to Configuration. The original
00279       differences have evolved out of the implementation.
00280   */
00281   class ValueTable {
00282   public:
00283     typedef ValueTable self; ///< Self reference type.
00284     typedef ValueTableImpl ImplType; ///< Implementation type.
00285 
00286     /// Table size.
00287     /// @return The number of value items in the table.
00288     size_t size() const;
00289     /// Generation.
00290     /// @return The generation number.
00291     Generation generation() const;
00292 
00293     /// Const access by index.
00294     /// @return The value item at index @a idx.
00295     ValueItem const& operator [] (
00296       ValueIndex idx ///< Index of item.
00297     ) const;
00298     /// Access by index.
00299     /// @return The value item at index @a idx.
00300     ValueItem& operator [] (
00301       ValueIndex idx ///< Index of item.
00302     );
00303 
00304     /// Force the existence of the root item in the table.
00305     /// @return @c this object.
00306     self& forceRootItem();
00307     /** Create a new item (value) with optional @a name
00308         The table must contain @a parent. If @a name is omitted, the item
00309         has an empty name.
00310         @return Index of the new value item.
00311     */
00312     Rv<ValueIndex> make(
00313       ValueIndex parent, ///< Index of parent for item.
00314       ValueType type, ///< Type of item.
00315       ConstBuffer const& name = NULL_BUFFER ///< Name (may be empty).
00316     );
00317 
00318     /// Test for not table existence.
00319     /// @return @c false if the implementation instance exists, @c true if not.
00320     bool operator ! () const;
00321     /// Test for table existence.
00322     /// @return @c true if the implementation instance exists, @c false if not.
00323     operator PseudoBool::Type() const;
00324     /// Reset to default constructed state.
00325     /// @return @c this object.
00326     self& reset();
00327 
00328     /** Allocate a local buffer.
00329         This buffer will persist until the implementation instance
00330         is destoyed.
00331         @return The allocated buffer.
00332     */
00333     Buffer alloc(size_t n);
00334   protected:
00335     typedef IntrusivePtr<ImplType> ImplPtr; ///< Smart pointer to implementation instance.
00336     ImplPtr _ptr; ///< Implementation instance.
00337 
00338     /// Force an implementation instance and return a pointer to it.
00339     ImplType* instance();
00340   };
00341 } // namespace detail
00342 
00343 /** Container for a configuration.
00344     This is a wrapper class that holds a shared reference to a configuration.
00345 */
00346 class Configuration {
00347   friend class Value;
00348 public:
00349   typedef Configuration self; ///< Self reference type.
00350 
00351   /** Check if configuration is (not) valid.
00352       @return @c true if this configuration is invalid, @c false otherwise.
00353   */
00354   bool operator ! () const;
00355   /** Check if the configuration is valid.
00356       @return The equivalent of @c true if this does @b not contain a value,
00357       the equivalent of @c false if it does.
00358   */
00359   operator detail::PseudoBool::Type () const;
00360   /** Get the root @c Value of the configuration.
00361       The root is always a group and has no name.
00362       @return The root value.
00363   */
00364   Value getRoot() const;
00365 
00366   /// Get the number of child values on the root value.
00367   size_t childCount() const;
00368   /** Root value child access by @a index
00369       @return The child or a @c Void value if there is no child with @a name.
00370   */
00371   Value operator [] (
00372     size_t idx ///< Index of child value.
00373   ) const;
00374   /** Root value child access by @a name.
00375       @return The child or a @c Void value if there is no child with @a name.
00376   */
00377   Value operator [] (
00378     ConstBuffer const& name
00379   ) const;
00380   /** Root value child access by @a name.
00381       @return The child or a @c Void value if there is no child with @a name.
00382   */
00383   Value operator [] (
00384     char const* name ///< Null terminated string.
00385   ) const;
00386 
00387   /** Find a value.
00388       @return The value if found, an void valid if not.
00389   */
00390   Value find(
00391     char const* path ///< configuration path to value.
00392   );
00393   /** Load a configuration from a file.
00394 
00395       @note Check the returned errata for problems during configuration
00396       load. It is probably not a good idea to use the configuration in
00397       any error are reported.
00398       @return A new @c Configuration and errata.
00399   */
00400   static Rv<self> loadFromPath(
00401     char const* path ///< file system path.
00402   );
00403   /** Allocate a local buffer of size @a n.
00404       This buffer will persist until the implementation instance
00405       is destroyed.
00406       @return The allocated buffer.
00407   */
00408   Buffer alloc(
00409     size_t n ///< requested size of buffer.
00410   );
00411 protected:
00412   detail::ValueTable _table; ///< Table of values from the configuration.
00413 };
00414 
00415 /** This holds a value from the configuration.
00416 
00417     @internal It is critical that none of the type specific subclasses define any data members
00418     so that instances can be freely converted to and from this base class.
00419 */
00420 class Value {
00421   friend class Configuration;
00422 public:
00423   typedef Value self; ///< Self reference type.
00424   /// Default constructors.
00425   /// Creates an @c NULL instance.
00426   Value();
00427   /// Destructor.
00428   ~Value();
00429 
00430   /// Get the type of value.
00431   ValueType getType() const;
00432   /// Test if this is a valid value.
00433   /// @return @c true if this contains a value, @c false otherwise.
00434   bool hasValue() const;
00435   /** Operator form of @c hasValue.
00436       @see hasValue
00437       @return @c true if this does @b not contain a value, @c false if it does.
00438   */
00439   bool operator ! () const;
00440   /** Logical form of @c hasValue for use in logical expressions.
00441       @see hasValue
00442       @return The equivalent of @c true if this does @b not contain a value,
00443       the equivalent of @c false if it does.
00444   */
00445   operator detail::PseudoBool::Type () const;
00446 
00447   /** Get the value text.
00448       @return The text in the configuration file for this item if the item
00449       is a scalar, an empty buffer otherwise.
00450   */
00451   ConstBuffer const& getText() const;
00452   /// Set the @a text for this value.
00453   self& setText(
00454     ConstBuffer const& text
00455   );
00456 
00457   /** Get local name.
00458       This gets the local name of the value. That is the name by which it
00459       is known to its parent container.
00460 
00461       @internal Only works for groups now. It should be made to work
00462       for lists. This would require allocating strings for each index,
00463       which should be shared across values. For instance, all values
00464       at index 1 should return the same string "1", not separately
00465       allocated for each value.
00466    */
00467   ConstBuffer const& getName() const;
00468   /** Get local index.
00469       This gets the local index for the value. This is the index which,
00470       if used on the parent, would yield this value.
00471       @return The local index.
00472    */
00473   size_t getIndex() const;
00474 
00475   /// Test for a literal value.
00476   /// @return @c true if the value is a literal,
00477   /// @c false if it is a container or invalid.
00478   bool isLiteral() const;
00479   /// Test for value container.
00480   /// @return @c true if the value is a container (can have child values),
00481   /// @c false otherwise.
00482   bool isContainer() const;
00483   /// Get the parent value.
00484   Value getParent() const;
00485   /// Test if this is the root value for the configuration.
00486   bool isRoot() const;
00487 
00488   /// Get the number of child values.
00489   size_t childCount() const;
00490   /** Child access by @a index
00491       @return The child or a @c Void value if there is no child with @a name.
00492   */
00493   Value operator [] (
00494     size_t idx ///< Index of child value.
00495   ) const;
00496   /** Child access by @a name.
00497       @return The child or a @c Void value if there is no child with @a name.
00498   */
00499   Value operator [] (
00500     ConstBuffer const& name
00501   ) const;
00502   /** Child access by @a name.
00503       @return The child or a @c Void value if there is no child with @a name.
00504   */
00505   Value operator [] (
00506     char const* name ///< Null terminated string.
00507   ) const;
00508 
00509   /** @name Creating child values.
00510 
00511       These methods all take an optional @a name argument. This is
00512       required if @c this is a @c Group and ignored if @c this is a @c
00513       List.
00514 
00515       These methods will fail if
00516       - @c this is not a container.
00517       - @c this is a @c Group and no @a name is provided.
00518 
00519       @note Currently for groups, duplicate names are not
00520       detected. The duplicates will be inaccessible by name but can
00521       still be found by index. This is a problem but I am still
00522       pondering the appropriate solution.
00523 
00524       @see isContainer
00525       @return The new value, or an invalid value plus errata on failure.
00526 
00527       @internal I original had this as a single method, but changed to
00528       separate per type.  Overall less ugly because we can get the
00529       arguments more useful.
00530   */
00531   //@{
00532   /// Create a @c String value.
00533   Rv<Value> makeString(
00534     ConstBuffer const& text, ///< String content.
00535     ConstBuffer const& name = detail::NULL_BUFFER///< Optional name of value.
00536   );
00537   /// Create an @c Integer value.
00538   Rv<Value> makeInteger(
00539     ConstBuffer const& text, ///< Text of number.
00540     ConstBuffer const& name = detail::NULL_BUFFER///< Optional name of value.
00541   );
00542   /// Create a @c Group value.
00543   Rv<Value> makeGroup(
00544     ConstBuffer const& name = detail::NULL_BUFFER///< Optional name of value.
00545   );
00546   /// Create a @c List value.
00547   Rv<Value> makeList(
00548     ConstBuffer const& name = detail::NULL_BUFFER///< Optional name of value.
00549   );
00550   /// Create a @c Path value.
00551   Rv<Value> makePath(
00552     Path const& path, ///< Path.
00553     ConstBuffer const& name = detail::NULL_BUFFER///< Optional name of value.
00554   );
00555   /// Create a child by type.
00556   /// Client must fill in any other required elements.
00557   Rv<Value> makeChild(
00558     ValueType type, ///< Type of child.
00559     ConstBuffer const& name = detail::NULL_BUFFER///< Optional name of value.
00560   );
00561   //@}
00562 
00563   /** Find a value.
00564       @return The value if found, an void valid if not.
00565   */
00566   Value find(
00567     ConstBuffer const& path ///< Path relative to this value.
00568   );
00569   /** Find a value.
00570       @return The value if found, an void valid if not.
00571   */
00572   Value find(
00573     char const* path ///< Path relative to this value.
00574   );
00575   /** Find a value using a precondensed path.
00576       @return The value if found, an void valid if not.
00577   */
00578   Value find(
00579     Path const& path ///< Path relative to this value.
00580   );
00581 
00582   /** Reset to default constructed state.
00583       @note This wrapper is reset, the value in the configuration is unchanged.
00584       @return @c this object.
00585   */
00586   self& reset();
00587 
00588   /// Set source line.
00589   /// @return @c this object.
00590   self& setSourceLine(
00591     int line ///< Line in source stream.
00592   );
00593   /// Set source column.
00594   /// @return @c this object.
00595   self& setSourceColumn(
00596     int col ///< Column in source stream.
00597   );
00598   /// Set the source location.
00599   self& setSource(
00600     int line, ///< Line in source stream.
00601     int col ///< Column in source stream.
00602   );
00603   /// Get source line.
00604   /// @return The line in the source stream for this value.
00605   int getSourceLine() const;
00606   /// Get source column.
00607   /// @return The column in the source stream for this value.
00608   int getSourceColumn() const;
00609 
00610 protected:
00611   // Note: We store an index and not a pointer because a pointer will go stale
00612   // if any items are added or removed from the underlying table.
00613   // Also, by storing the configuration, we hold it in memory as long as a Value
00614   // is in client hands.
00615   Configuration _config; ///< The configuration for this value.
00616   detail::ValueIndex _vidx; ///< Index of item.
00617 
00618   static Buffer const NULL_BUFFER; ///< Empty buffer to return on method failures.
00619 
00620   /// Construct from raw data.
00621   Value(
00622     Configuration cfg, ///< Source configuration.
00623     detail::ValueIndex vidx  ///< Index of value.
00624   );
00625 
00626   /** Get raw item pointer.
00627       @note This pointer is unstable and must be recomputed on each method invocation.
00628       @return The item pointer or @c NULL if this value is invalid.
00629   */
00630   detail::ValueItem* item();
00631   /** Get constant raw item pointer.
00632       @note This pointer is unstable and must be recomputed on each method invocation.
00633       @return The item pointer or @c NULL if this value is invalid.
00634   */
00635   detail::ValueItem const* item() const;
00636 };
00637 
00638 // Inline methods.
00639 namespace detail {
00640   inline bool ValueTable::operator ! () const { return ! _ptr; }
00641   inline ValueTable::operator PseudoBool::Type () const { return _ptr ? PseudoBool::TRUE : PseudoBool::FALSE; }
00642   inline size_t ValueTable::size() const { return _ptr ? _ptr->_values.size() : 0; }
00643   inline Generation ValueTable::generation() const { return _ptr ? _ptr->_generation : Generation(0); }
00644   inline ValueItem const& ValueTable::operator [] (ValueIndex idx) const { return const_cast<self*>(this)->operator [] (idx); }
00645   inline ValueTable& ValueTable::reset() { _ptr = 0; return *this; }
00646 
00647   inline ValueItem::ValueItem() : _type(VoidValue) {}
00648   inline ValueItem::ValueItem(ValueType type) : _type(type) {}
00649   inline ValueType ValueItem::getType() const { return _type; }
00650 }
00651 
00652 inline Value::~Value() { }
00653 inline Value::Value() : _vidx(detail::NULL_VALUE_INDEX) {}
00654 inline Value::Value(Configuration cfg, detail::ValueIndex vidx) : _config(cfg), _vidx(vidx) { }
00655 inline bool Value::hasValue() const { return _config && _vidx != detail::NULL_VALUE_INDEX; }
00656 inline Value::operator detail::PseudoBool::Type () const { return this->hasValue() ? detail::PseudoBool::TRUE : detail::PseudoBool::FALSE; }
00657 inline bool Value::operator ! () const { return ! this->hasValue(); }
00658 inline ValueType Value::getType() const { return this->hasValue() ? _config._table[_vidx]._type : VoidValue; }
00659 inline ConstBuffer const& Value::getText() const {
00660   return this->hasValue() ? _config._table[_vidx]._text : detail::NULL_CONST_BUFFER;
00661 }
00662 inline Value& Value::setText(ConstBuffer const& text) {
00663   detail::ValueItem* item = this->item();
00664   if (item) item->_text = text;
00665   return *this;
00666 }
00667 inline ConstBuffer const& Value::getName() const {
00668   detail::ValueItem const* item = this->item();
00669   return item ? item->_name : detail::NULL_CONST_BUFFER;
00670 }
00671 inline size_t Value::getIndex() const {
00672   detail::ValueItem const* item = this->item();
00673   return item ? item->_local_index : 0;
00674 }
00675   
00676 inline bool Value::isLiteral() const { return 0 != (detail::IS_LITERAL & detail::Type_Property[this->getType()]); }
00677 inline bool Value::isContainer() const { return 0 != (detail::IS_CONTAINER & detail::Type_Property[this->getType()]); }
00678 inline Value Value::getParent() const { return this->hasValue() ? Value(_config, _config._table[_vidx]._parent) : Value(); }
00679 inline bool Value::isRoot() const { return this->hasValue() && _vidx == 0; }
00680 inline Value& Value::reset() { _config = Configuration(); _vidx = detail::NULL_VALUE_INDEX; return *this; }
00681 inline detail::ValueItem* Value::item() { return this->hasValue() ? &(_config._table[_vidx]) : 0; }
00682 inline detail::ValueItem const* Value::item() const { return const_cast<self*>(this)->item(); }
00683 inline Value Value::operator [] (char const* name) const { return (*this)[ConstBuffer(name, strlen(name))]; }
00684 inline size_t Value::childCount() const {
00685   detail::ValueItem const* item = this->item();
00686   return item ? item->_children.size() : 0;
00687 }
00688 inline Value Value::find(char const* path) { return this->find(ConstBuffer(path, strlen(path))); }
00689 inline int Value::getSourceLine() const {
00690   detail::ValueItem const* item = this->item();
00691   return item ? item->_srcLine : 0;
00692 }
00693 inline int Value::getSourceColumn() const {
00694   detail::ValueItem const* item = this->item();
00695   return item ? item->_srcColumn : 0;
00696 }
00697 inline Value& Value::setSourceLine(int line) {
00698   detail::ValueItem* item = this->item();
00699   if (item) item->_srcLine = line;
00700   return *this;
00701 }
00702 inline Value& Value::setSourceColumn(int col) {
00703   detail::ValueItem* item = this->item();
00704   if (item) item->_srcColumn = col;
00705   return *this;
00706 }
00707 inline Value& Value::setSource(int line, int col) {
00708   detail::ValueItem* item = this->item();
00709   if (item) {
00710     item->_srcLine = line;
00711     item->_srcColumn = col;
00712   }
00713   return *this;
00714 }
00715 
00716 inline Path::ImplType::ImplType() { }
00717 
00718 inline Path::Path() { }
00719 inline Path::ImplType* Path::instance() { if (!_ptr) _ptr = new ImplType; return _ptr.get(); }
00720 inline Path& Path::append(ConstBuffer const& tag) { this->instance()->_elements.push_back(tag); return *this; }
00721 inline Path& Path::append(size_t index) { this->instance()->_elements.push_back(ConstBuffer(0, index)); return *this; }
00722 inline size_t Path::count() const { return _ptr ? _ptr->_elements.size() : 0; }
00723 inline ConstBuffer const& Path::operator [] (size_t idx) const { return _ptr ? _ptr->_elements[idx] : detail::NULL_CONST_BUFFER; }
00724 
00725 inline Path::Parser::Parser() { }
00726 inline Path::Parser::Parser( ConstBuffer const& text ) : _input(text), _c(text._ptr) { }
00727 inline bool Path::Parser::hasInput() const { return _input._ptr && _input._ptr + _input._size > _c; }
00728 
00729 inline bool Configuration::operator ! () const { return ! _table; }
00730 inline Configuration::operator detail::PseudoBool::Type() const { return _table.operator detail::PseudoBool::Type(); }
00731 inline Value Configuration::find( char const* path ) { return this->getRoot().find(path); }
00732 inline Buffer Configuration::alloc(size_t n) { return _table.alloc(n);  }
00733 inline size_t Configuration::childCount() const { return this->getRoot().childCount(); }
00734 inline Value Configuration::operator [] (size_t idx) const { return (this->getRoot())[idx]; }
00735 inline Value Configuration::operator [] ( ConstBuffer const& name ) const { return (this->getRoot())[name]; }
00736 inline Value Configuration::operator [] ( char const* name ) const { return (this->getRoot())[name]; }
00737 
00738 }} // namespace ts::config
00739 
00740 # endif

Generated by  doxygen 1.7.1