4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 // Stefan Bund <g0dil@berlios.de>
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.
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.
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.
24 \brief ScopedDirectory public header */
26 #ifndef HH_SENF_Scheduler_Console_ScopedDirectory_
27 #define HH_SENF_Scheduler_Console_ScopedDirectory_ 1
30 #include <boost/utility.hpp>
31 #include <boost/type_traits/is_convertible.hpp>
33 #include "LazyDirectory.hh" // For ScopedDirectory template default arg
35 //#include "ScopedDirectory.mpp"
36 ///////////////////////////////hh.p////////////////////////////////////////
41 namespace detail { struct OwnedNodeFactory {}; }
43 /** \brief Internal: Marker base class for all ScopedDirectory proxies
45 class ScopedDirectoryBase
48 DirectoryNode & node() const; ///< Access the proxied DirectoryNode
49 operator DirectoryNode & () const; ///< Access the proxied DirectoryNode
51 ///////////////////////////////////////////////////////////////////////////
52 ///\name Proxied members (see DirectoryNode)
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;
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;
76 ScopedDirectoryBase();
77 ~ScopedDirectoryBase();
80 DirectoryNode::ptr node_;
83 /** \brief DirectoryNode member proxy
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
95 ScopedDirectory<MyClass> configDir;
97 MyClass() : configDir(this)
104 The ScopedDirectory proxy implements 'add()' to add new children to the proxied
105 DirectoryNode. All add() variants supported by DirectoryNode are supported by
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
117 template <class Owner>
118 class ScopedDirectory : public ScopedDirectoryBase
121 ///////////////////////////////////////////////////////////////////////////
126 ///////////////////////////////////////////////////////////////////////////
127 ///\name Structors and default members
130 explicit ScopedDirectory(Owner * owner);
133 ///////////////////////////////////////////////////////////////////////////
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);
157 class ScopedDirectory<void> : public ScopedDirectoryBase
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);
174 ///////////////////////////////hh.e////////////////////////////////////////
175 #include "ScopedDirectory.cci"
176 //#include "ScopedDirectory.ct"
177 #include "ScopedDirectory.cti"
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"