Fix documentation build under maverick (doxygen 1.7.1)
[senf.git] / senf / Utils / Console / ScopedDirectory.hh
1 // $Id$
2 //
3 // Copyright (C) 2008
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief ScopedDirectory public header */
25
26 #ifndef HH_SENF_Scheduler_Console_ScopedDirectory_
27 #define HH_SENF_Scheduler_Console_ScopedDirectory_ 1
28
29 // Custom includes
30 #include <boost/utility.hpp>
31 #include <boost/type_traits/is_convertible.hpp>
32 #include "Node.hh"
33 #include "LazyDirectory.hh" // For ScopedDirectory template default arg
34
35 //#include "ScopedDirectory.mpp"
36 //-/////////////////////////////////////////////////////////////////////////////////////////////////
37
38 namespace senf {
39 namespace console {
40
41     namespace detail { struct OwnedNodeFactory {}; }
42
43     /** \brief Internal: Marker base class for all ScopedDirectory proxies
44      */
45     class ScopedDirectoryBase
46     {
47     public:
48         DirectoryNode & node() const;   ///< Access the proxied DirectoryNode
49         operator DirectoryNode & () const; ///< Access the proxied DirectoryNode
50
51         //-////////////////////////////////////////////////////////////////////////
52         ///\name Proxied members (see DirectoryNode)
53         //\{
54
55         GenericNode::ptr remove(std::string const & name);
56         bool hasChild(std::string const & name) const;
57         DirectoryNode & getDirectory(std::string const & name) const;
58         DirectoryNode & operator[](std::string const & name) const;
59         CommandNode & getCommand(std::string const & name) const;
60         CommandNode & operator()(std::string const & name) const;
61         GenericNode & get(std::string const & name) const;
62         DirectoryNode::ChildrenRange children() const;
63         DirectoryNode & doc(std::string const & doc);
64         std::string const & name() const;
65         bool active() const;
66         std::string path() const;
67         std::string path(DirectoryNode const & root) const;
68         boost::shared_ptr<DirectoryNode> parent() const;
69         GenericNode::ptr unlink();
70         void help(std::ostream & output) const;
71         std::string shorthelp() const;
72
73         //\}
74
75     protected:
76         ScopedDirectoryBase();
77         ~ScopedDirectoryBase();
78
79     private:
80         DirectoryNode::ptr node_;
81     };
82
83     /** \brief DirectoryNode member proxy
84
85         ScopedDirectory is used whenever a class wants to manage it's own directory. The class
86         allows to declare the directory as a public member object. This allows the user of the class
87         to register the directory in the command tree. By using the proxy, the node is automatically
88         detached from the tree (and thereby destroyed) when the object (and thereby the proxy) is
89         destroyed.
90
91         \code
92         class MyClass
93         {
94         public:
95             ScopedDirectory<MyClass> configDir;
96
97             MyClass() : configDir(this)
98             {
99                 configDir.add(...);
100             }
101         };
102         \endcode
103
104         The ScopedDirectory proxy implements 'add()' to add new children to the proxied
105         DirectoryNode. All add() variants supported by DirectoryNode are supported by
106         ScopedDirectory.
107
108         \idea This proxy could be made obsolete by allowing to allocate node objects
109             statically. This could be achieved by moving back to an intrusive_ptr implementation for
110             normal pointing needs with an added twist: Give each node a smart_ptr member pointing to
111             itself with a null deleter. This allows to create weak_ptr's to the nodes which will
112             automatically expire when the node is deleted (either statically or by the
113             intrusive_ptr).
114
115         \ingroup node_tree
116       */
117     template <class Owner>
118     class ScopedDirectory : public ScopedDirectoryBase
119     {
120     public:
121         //-////////////////////////////////////////////////////////////////////////
122         // Types
123
124         typedef Owner owner;
125
126         //-////////////////////////////////////////////////////////////////////////
127         ///\name Structors and default members
128         //\{
129
130         explicit ScopedDirectory(Owner * owner);
131
132         //\}
133         //-////////////////////////////////////////////////////////////////////////
134
135         template <class NodeType>
136         NodeType & add(std::string const & name, boost::shared_ptr<NodeType> node);
137         template <class NodeType>
138         NodeType & add(std::string const & name, NodeType & node,
139                        typename boost::enable_if< boost::is_convertible<NodeType &, GenericNode &> >::type * = 0);
140         template <class Factory>
141         typename Factory::result_type add(std::string const & name, Factory const & factory,
142                                           typename boost::enable_if< boost::is_convertible<Factory*, detail::OwnedNodeFactory*> >::type * = 0);
143         template <class Factory>
144         typename Factory::result_type add(std::string const & name, Factory const & factory,
145                                           typename boost::enable_if< boost::is_convertible<Factory*, detail::NodeFactory*> >::type * = 0,
146                                           typename boost::disable_if< boost::is_convertible<Factory*, detail::OwnedNodeFactory*> >::type * = 0);
147
148     protected:
149
150     private:
151         Owner * owner_;
152     };
153
154 #ifndef DOXYGEN
155
156     template <>
157     class ScopedDirectory<void> : public ScopedDirectoryBase
158     {
159     public:
160         template <class NodeType>
161         NodeType & add(std::string const & name, boost::shared_ptr<NodeType> node);
162         template <class NodeType>
163         NodeType & add(std::string const & name, NodeType & node,
164                        typename boost::enable_if< boost::is_convertible<NodeType &, GenericNode &> >::type * = 0);
165         template <class Factory>
166         typename Factory::result_type add(std::string const & name, Factory const & factory,
167                                           typename boost::enable_if< boost::is_convertible<Factory*, detail::NodeFactory*> >::type * = 0);
168     };
169
170 #endif
171
172 }}
173
174 //-/////////////////////////////////////////////////////////////////////////////////////////////////
175 #include "ScopedDirectory.cci"
176 //#include "ScopedDirectory.ct"
177 #include "ScopedDirectory.cti"
178 #endif
179
180 \f
181 // Local Variables:
182 // mode: c++
183 // fill-column: 100
184 // comment-column: 40
185 // c-file-style: "senf"
186 // indent-tabs-mode: nil
187 // ispell-local-dictionary: "american"
188 // compile-command: "scons -u test"
189 // End: