#pragma once namespace Bootil { namespace Data { // // The tree is a simple recursive Name-Value data structure. // Each node can have a key, a value and multiple children nodes // template class BOOTIL_EXPORT TreeT { public: typedef TreeT ThisClass; typedef typename std::list< ThisClass > List; public: TreeT() { m_Info = 0; } const TString & Name() const; void Name( const TString & name ); const TString & Value() const; void Value( const TString & value ); // // Returns true if we have some children // // BOOTIL_FOREACH[_CONST]( child, mytree.Children(), Bootil::Data::Tree::List ) // { // // Do stuff to 'child' // } // bool HasChildren() const; // // Returns a list of children. // const List & Children() const { return m_Children; } List & Children() { return m_Children; } // // Adding and setting children // mychild = AddChild(); [adds an unnamed child] // mychild = AddChild( "Name" ); [adds a named child] // mychild = SetChild( "Name", "Value" ); [adds a named child with value] // mychild = GetChild( "Name" ); [returns child, or creates child if not exists] // bool b = HasChild( "Name" ); [returns true if child exists] // mychild = GetChildNum( 7 ); [returns 7th child, or creates 7 child if not exists (if empty, will create 7 children and return the 7th etc)] TreeT & AddChild(); TreeT & AddChild( TString name ); TreeT & SetChild( TString strKey, TString strValue ); TreeT & SetChild( TString strValue ) { return SetChild( "", strValue ); } TreeT & GetChild( const TString & name ); bool HasChild( const TString & name ) const; TreeT & GetChildNum( int iNum ); // // Getting Child Value // value = Value( "Name", "Default" ) [returns 'Default' if 'Name' isn't found] // TString ChildValue( const TString & name, const TString & Default = "" ) const; // // Setting non-string values // template TreeT & SetChildVar( TString strKey, TValue strValue ); template TValue ChildVar( TString strKey, TValue Default ) const; template void Var( TValue strValue ); template TValue Var() const; template bool IsVar() const; // Utility methods // template TString VarToString( TValue var ) const; template TValue StringToVar( const TString & str ) const; template unsigned char VarID() const; bool IsBranch() const { return m_Info == 0; } // // Clean up // void Clear() { m_Children.clear(); } protected: TString m_Name; TString m_Value; unsigned char m_Info; List m_Children; }; // // We have a normal version and a wide version by default // Although the wide version is probably a waste of time since // nothing supports it right now. // typedef TreeT Tree; typedef TreeT TreeW; // // Template function definitions // template const TString & TreeT::Name() const { return m_Name; } template void TreeT::Name( const TString & name ) { m_Name = name; } template const TString & TreeT::Value() const { return m_Value; } template void TreeT::Value( const TString & value ) { m_Info = 1; m_Value = value; } template TreeT & TreeT::AddChild() { { TreeT t; m_Children.push_back( t ); } TreeT & t = m_Children.back(); return t; } template TreeT & TreeT::AddChild( TString name ) { TreeT & tree = AddChild(); tree.Name( name ); return tree; } template TreeT & TreeT::SetChild( TString strKey, TString strValue ) { TreeT & tchild = AddChild( strKey ); tchild.Value( strValue ); return tchild; } template TString TreeT::ChildValue( const TString & name, const TString & Default ) const { BOOTIL_FOREACH_CONST( a, Children(), typename List ) { if ( a->Name() == name ) { return a->Value(); } } return Default; } template bool TreeT::HasChild( const TString & name ) const { BOOTIL_FOREACH_CONST( a, Children(), typename List ) { if ( a->Name() == name ) { return true; } } return false; } template TreeT & TreeT::GetChild( const TString & name ) { BOOTIL_FOREACH( a, Children(), typename List ) { if ( a->Name() == name ) { return ( *a ); } } return AddChild( name ); } template TreeT & TreeT::GetChildNum( int iNum ) { BOOTIL_FOREACH( a, Children(), typename List ) { if ( iNum == 0 ) { return ( *a ); } iNum--; } while ( iNum > 0 ) { AddChild(); } return AddChild(); } template bool TreeT::HasChildren() const { return !m_Children.empty(); } template template TreeT & TreeT::SetChildVar( TString strKey, TValue var ) { TreeT & tchild = AddChild( strKey ); tchild.Var( var ); return tchild; } template template TValue TreeT::ChildVar( TString strKey, TValue varDefault ) const { BOOTIL_FOREACH_CONST( a, Children(), typename List ) { if ( a->Name() == strKey ) { return a->template Var(); } } return varDefault; } template template void TreeT::Var( TValue var ) { m_Info = VarID(); m_Value = VarToString( var ); } template template TValue TreeT::Var() const { return StringToVar( Value() ); } template template bool TreeT::IsVar() const { return m_Info == VarID(); } } }