Finished libSocket and libUtils documentation
g0dil [Fri, 9 Feb 2007 14:15:40 +0000 (14:15 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@196 270642c3-0616-0410-b53a-bc976706d245

32 files changed:
Packets/Mainpage.dox
Scheduler/Doxyfile
Scheduler/Mainpage.dox [new file with mode: 0644]
Scheduler/ReadHelper.cci
Scheduler/ReadHelper.ct
Scheduler/ReadHelper.cti
Scheduler/ReadHelper.hh
Scheduler/ReadHelper.ih
Scheduler/Scheduler.cc
Scheduler/Scheduler.cci
Scheduler/Scheduler.cti
Scheduler/Scheduler.hh
Scheduler/WriteHelper.ct
Scheduler/WriteHelper.cti
Scheduler/WriteHelper.hh
Utils/DaemonTools.cc
Utils/DaemonTools.hh
Utils/Doxyfile
Utils/Exception.cc
Utils/Exception.cci [moved from Scheduler/Scheduler.ct with 59% similarity]
Utils/Exception.hh
Utils/Mainpage.dox [new file with mode: 0644]
Utils/MicroTime.cc
Utils/MicroTime.hh
Utils/SafeBool.hh
Utils/TypeInfo.cc
Utils/TypeInfo.hh
Utils/intrusive_refcount.cci
Utils/intrusive_refcount.hh
Utils/membind.hh
doclib/filter.pl
doclib/senf.css

index 2b25b40..bfb1120 100644 (file)
     ethernet header). Together with it's support classes (especially
     senf::PacketRegistryMixin) this class greatly simplifies
     implementing the needed table lookups.
+
+    \todo The Packet Libarary really needs a refactoring of the public
+       interfaface ...
+
+    \idea Add the Handle-Body idiom to the mix with a PacketRef (or
+       HeaderRef or InterpreterRef or whatever class). This would
+       have members for all the API defined in Packet now. \c
+       operator-> would return a parser object to interpret the
+       data. This would make awayy with the inheritance relationship
+       ...
+
+    \idea Templating the parsers on the iterator type does not
+       introduce additional coupling (because of the inlining) but
+       looking at it after the fact it looks like severe overdesign
+       and it does introduce some problems (e.g. rebind and all this
+       entails). If we just implement all parsers for
+       Packet::byte_iterator they are no tmplates any more which
+       should simplify things a log.
+
+    \idea we need some better and automatic checking on data access
+       especially after data has changed. Idea 1: give the parser the
+       end iterator as additional member. Enforce, that all parsers
+       must ultimately be based on ParseInt and have ParseInt check
+       against end() at construction time. Idea 2: add a dirty flag
+       to the interpreters. Set this flag whenever the packet is
+       changed and recall check() in operator-> of the PacketRef
+       object if the packet is dirty. Maybe we need both and make
+       them tunable.
  */
 
 \f
index 38eada5..7ea57be 100644 (file)
@@ -3,3 +3,4 @@
 PROJECT_NAME = libScheduler
 TAGFILES = "$(TOPDIR)/Utils/doc/Utils.tag"
 GENERATE_TAGFILE = doc/Scheduler.tag
+ALPHABETICAL_INDEX = NO
diff --git a/Scheduler/Mainpage.dox b/Scheduler/Mainpage.dox
new file mode 100644 (file)
index 0000000..6084482
--- /dev/null
@@ -0,0 +1,33 @@
+namespace senf {
+
+/** \mainpage The SENF Scheduler Library
+
+    The Scheduler library provides a simple yet flexible abstraction
+    of the standard asynchronous UNIX mainloop utilizing \c select or
+    \c poll. The Scheduler library is based on the highly efficient
+    (but linux specific) \c epoll() system call.
+
+    The library provides 
+    \li a central \ref Scheduler singleton and 
+    \li \ref ReadHelper and \ref WriteHelper templates to simplify
+       common tasks.
+
+    In it's current incarnation, the library only supports network
+    file handles (including pipes etc) and simple timers (especially
+    it does not support asynchronous notification for on-disc file
+    transfers etc). Additional features will be added:
+    \li UNIX signal support
+    \li async IO support for local (disc) file handles
+    \li multi threading support
+    \li IPC support for multithreaded applications
+ */
+
+}
+
+\f
+// Local Variables:
+// mode: c++
+// mode: flyspell
+// mode: auto-fill
+// ispell-local-dictionary: "american"
+// End:
index 3d1a0aa..c85bb25 100644 (file)
@@ -1,19 +1,36 @@
 // $Id$
 //
+// Copyright (C) 2006 Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 // Copyright (C) 2006 
 
-// Definition of inline non-template functions
+/** \file
+    \brief ReadHelper inline non-template implementation */
 
 // Custom includes
 
 #define prefix_ inline
 ///////////////////////////////cci.p///////////////////////////////////////
 
-prefix_ senf::ReadUntil::ReadUntil(std::string target_)
+prefix_ senf::ReadUntil::ReadUntil(std::string const & target_)
     : target(target_)
 {}
 
-prefix_ std::string::size_type senf::ReadUntil::operator()(std::string data)
+prefix_ std::string::size_type senf::ReadUntil::operator()(std::string const & data)
 {
     return data.find(target);
 }
index 6a5d0b7..83a557a 100644 (file)
@@ -1,8 +1,25 @@
 // $Id$
 //
+// Copyright (C) 2006 Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 // Copyright (C) 2006 
 
-// Definition of non-inline template functions
+/** \file
+    \brief ReadHelper non-inline template implementation */
 
 #include "ReadHelper.ih"
 
@@ -52,6 +69,7 @@ template <class Handle>
 prefix_ void senf::ReadHelper<Handle>::process(Handle handle,
                                                       senf::Scheduler::EventId event)
 {
+    /** \fixme Move the done() calls to outside the try/catch block */
     try {
        if (event != senf::Scheduler::EV_READ)
            throw SystemException(EPIPE);
index 2e9a533..819b0b6 100644 (file)
@@ -1,8 +1,25 @@
 // $Id$
 //
+// Copyright (C) 2006 Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 // Copyright (C) 2006 
 
-// Definition of inline template functions
+/** \file
+    \brief ReadHelper inline template implementation */
 
 #include "ReadHelper.ih"
 
@@ -24,7 +41,7 @@ template <class Handle>
 template <class Predicate>
 prefix_ typename senf::ReadHelper<Handle>::ptr
 senf::ReadHelper<Handle>::dispatch(Handle handle, std::string::size_type maxSize,
-                                          Predicate predicate, Callback callback)
+                                   Predicate const & predicate, Callback callback)
 {
     return ptr(new ReadHelper(handle, maxSize, 
                              new typename InternalPredicate::template Dispatcher<Predicate>(predicate),
index 39ea480..23d1157 100644 (file)
@@ -1,7 +1,25 @@
 // $Id$
 //
+// Copyright (C) 2006 Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 // Copyright (C) 2006 
 
+/** \file
+    \brief ReadHelper public header */
 
 #ifndef HH_ReadHelper_
 #define HH_ReadHelper_ 1
 namespace senf {
 
 
-    /** \brief
+    /** \brief Asyncronous reading helper 
+
+       This class provides a simple asynchronous reading facility. This helper will register with
+       the Scheduler and read incoming data. It will collect the data until a specific numbner of
+       bytes has been read or some Predicate evaluated on the data read thus far signals end of
+       data.
+
+       The ReadHelper accepts the same flexible file handle interfaces as the Scheduler.
+       
+       The callback must take a ReadHelper::ptr argument. Using this ReadHelper instance, the
+       callback can access the data read or retrieve state information.
+
+       The ReadHelper separates the data into two parts: data() will return the matched data,
+       tail() will return any surplus data already read. If you don't specify a predicate, tail()
+       will always be empty (there may however some data be left in the socket input buffer after
+       the ReadHelper returns).
+
+       The predicate is any class instance with an <tt>operator(std::string const &)</tt>. This
+       operator is called, whenever some data has been read. If the data is not yet complete, the
+       predicate must return \c std::string::npos. If the ReadHelper should stop readeing more
+       data, the predicate must return the number of bytes which are to be considered 'matched'.
 
        \todo Move all not Handle dependent members to a ReadHandleBase class
+       \todo Add an optional <tt>std::string const & tail</tt> argument to the constructors which
+           takes the tail() of a previous ReadHelper instance.
      */
     template <class Handle>
     class ReadHelper
@@ -33,34 +73,56 @@ namespace senf {
         ///////////////////////////////////////////////////////////////////////////
         // Types
        
-       typedef boost::intrusive_ptr<ReadHelper> ptr;
-       typedef boost::function<void (ptr)> Callback;
+       typedef boost::intrusive_ptr<ReadHelper> ptr; ///< Smart pointer type for this class
+       typedef boost::function<void (ptr)> Callback; ///< Callback type
 
         ///////////////////////////////////////////////////////////////////////////
         ///\name Structors and default members
         ///@{
 
        static ptr dispatch(Handle handle, std::string::size_type maxSize, 
-                           Callback callback);
+                           Callback callback); ///< Register new ReadHandler instance
+                                        /**< The registered Callback will be called after \a maxSize
+                                            bytes have been read or EOF or some error is
+                                            encountered.
+                                            \post The returned ReadHelper instance is registered
+                                                with the Scheduler to handle read events.
+                                            \param[in] handle file descriptor or handle providing
+                                                the Handle interface defined above.
+                                            \param[in] maxSize maximum number of bytes to read
+                                            \param[in] cb callback
+                                            \returns Smart pointer to new ReadHelper instance */
 
        template <class Predicate>
-       static ptr dispatch(Handle handle, std::string::size_type maxSize, Predicate predicate,
-                           Callback callback);
+       static ptr dispatch(Handle handle, std::string::size_type maxSize, Predicate const & predicate,
+                           Callback callback); ///< Register new ReadHelper instance
+                                        /**< The registered Callback will be called after the \a
+                                            predicate returns a Value other than \c
+                                            std::string::npos, \a maxSize bytes have been read, or
+                                            EOF or some error condition is encountered.
+                                            \post The returned ReadHelper instance is registered
+                                                with the Scheduler to handle read events
+.                                           \param[in] handle file descriptor or handle providing
+                                                the Handle interface defined above.
+                                            \param[in] maxSize maximum number of bytes to read
+                                            \param[in] predicate predicate to check
+                                            \param[in] cb callback
+                                            \returns smart pointer to new ReadHelper instance */
 
         ///@}
         ///////////////////////////////////////////////////////////////////////////
 
-       Handle handle() const;
-       unsigned maxSize() const;
+       Handle handle() const;          ///< Access the handle object
+       unsigned maxSize() const;       ///< Return maximum number of bytes to be read
 
-       std::string const & data() const;
-       std::string const & tail() const;
+       std::string const & data() const; ///< return data read
+       std::string const & tail() const; ///< return data read but not matched by the predicate
 
-       bool complete() const;
-       bool error() const;
-       void throw_error() const;
+       bool complete() const;          ///< Check wether the read has completed successfully
+       bool error() const;             ///< Check for error condition
+       void throw_error() const;       ///< If an error occured, throw it
 
-       void revoke();
+       void revoke();                  ///< Remove the ReadHelper from the scheduler
 
     protected:
 
@@ -84,10 +146,18 @@ namespace senf {
        bool complete_;
     };
 
+    /** \brief ReadHelper predicate matching an arbitrary string
+       
+       This predicate will terminate the read when the data read matches a given fixed string. All
+       data up to and including the string matched is considered to be part of the data() portion,
+       everything after the matched string is placed into the tail().
+
+       \see ReadHelper
+     */
     struct ReadUntil
     {
-        ReadUntil(std::string target);
-       std::string::size_type operator()(std::string data);
+        ReadUntil(std::string const & target);
+       std::string::size_type operator()(std::string const & data);
        std::string target;
     };
 
@@ -103,4 +173,6 @@ namespace senf {
 \f
 // Local Variables:
 // mode: c++
+// c-file-style: "senf"
+// fill-column: 100
 // End:
index bca58bc..5df6164 100644 (file)
@@ -1,7 +1,26 @@
 // $Id$
 //
+// Copyright (C) 2006 Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 // Copyright (C) 2006 
 
+/** \file
+    \brief ReadHelper internal header */
+
 #ifndef IH_ReadHelper_
 #define IH_ReadHelper_ 1
 
 namespace senf {
 
 
+    /** \brief Abstract predicate interface
+       \internal
+     */
     template <class Handle>
     struct ReadHelper<Handle>::InternalPredicate
     {
        virtual ~InternalPredicate() {}
+
+       /** \brief template to runtime polymorphic barrier for the predicate interface
+           \internal
+
+           \implementation This class will provide a polymorphic
+               wrapper around the non-polymorphic ReadHelper
+               predicate. This is used, so the predicate can be
+               specified as an arbitrary callable object (even a
+               boost::function or a Boost.Lambda expression) without
+               imposing any inheritance relationship on the predicate
+        */
        template <class Predicate>
        struct Dispatcher
            : public ReadHelper<Handle>::InternalPredicate
index fbc917d..f7509bc 100644 (file)
@@ -21,6 +21,7 @@
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 /** \file
+    \brief Scheduler non-inline non-template implementation
 
     \idea Implement signal handling (See source for more discussion
     about this) 
@@ -28,7 +29,9 @@
     \idea Multithreading support: To support multithreading, the
     static member Scheduler::instance() must return a thread-local
     value (that is Scheduler::instance() must allocate one Scheduler
-    instance per thread)
+    instance per thread). Another possibility would be to distribute
+    the async load unto several threads (one scheduler for multiple
+    threads)
  */
 
 // Here a basic concept of how to add signal support to the scheduler:
@@ -69,8 +72,6 @@
 // with the scheduler must be blocked as soon as it is registered with
 // the scheduler.
 
-// Definition of non-inline non-template functions
-
 #include "Scheduler.hh"
 //#include "Scheduler.ih"
 
@@ -211,10 +212,10 @@ prefix_ void senf::Scheduler::process()
            if (spec.cb_hup)
                spec.cb_hup(EV_HUP);
            else if (ev.events & EPOLLERR) {
-               /// \fixme This is stupid, if cb_write and cb_read are
-               /// the same. The same below. We really have to
-               /// exactly define sane semantics of what to do on
-               /// EPOLLHUP and EPOLLERR.
+               /** \fixme This is stupid, if cb_write and cb_read are
+                   the same. The same below. We really have to
+                   exactly define sane semantics of what to do on
+                   EPOLLHUP and EPOLLERR. */
                if (spec.cb_write) spec.cb_write(EV_HUP);
                if (spec.cb_read) spec.cb_read(EV_HUP);
            }
index f752d3e..028b372 100644 (file)
@@ -20,7 +20,9 @@
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-// Definition of inline non-template functions
+/** \file
+    \brief Scheduler inline non-template implementation
+ */
 
 //#include "Scheduler.ih"
 
index 62bfe38..ec12226 100644 (file)
@@ -20,7 +20,9 @@
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-// Definition of inline template functions
+/** \file
+    \brief Scheduler inline template implementation
+ */
 
 //#include "Scheduler.ih"
 
index 819d70e..a8dc456 100644 (file)
@@ -20,8 +20,8 @@
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-/** \mainpage The SENF Scheduler library
-
+/** \file
+    \brief Scheduler public header
  */
 
 #ifndef HH_Scheduler_
@@ -44,14 +44,28 @@ namespace senf {
 
     /** \brief Singleton class to manage the event loop
 
-        This class manages a single select() type event loop. A
-        customer of this class may register any number of file
-        descriptiors with this class and pass callback functions to be
-        called on input, output or error. This functions are specified
-        using boost::function objects
-
-       \todo Fix EventId parameter (probably to int) to allow |-ing
-       without casting ...
+        This class manages a single select() type event loop. A customer of this class may register
+        any number of file descriptiors with this class and pass callback functions to be called on
+        input, output or error. This functions are specified using boost::function objects (See <a
+        href="http://www.boost.org/doc/html/function.html">Boost.Function</a>)
+
+       The Scheduler is based on a generic handle representation. The only information needed from
+       a handle, is the intrinsic file descriptor. Any object for which the statement
+       \code
+         int fd = retrieve_filehandle(object);
+       \endcode
+       is valid and places the relevent file descriptor into fd can be used as a Handle type. There
+       is an implementation of retrieve_filehandle(int) within the library to handle explicit file
+       descrptors. The <a href="../../../Socket/doc/html/index.html">Socket library</a> provides an
+       implementation of <tt>retrive_filehandle(FileHandle handle)</tt>. If you want to support
+       some other handle type, just define an apropriate \c retrieve_filehandle function <em>in
+       that types namespace</em>.
+
+       It is important to note, that for every combination of file descriptor and event, only a \e
+       single handler may be installed. Installing more handlers does not make sense. If you need
+       to distribute data to serveral interested parties, you must take care of this yourself.
+
+       \todo Fix EventId parameter (probably to int) to allow |-ing without casting ...
       */
     class Scheduler
         : boost::noncopyable
@@ -60,16 +74,24 @@ namespace senf {
         ///////////////////////////////////////////////////////////////////////////
         // Types
 
+       /// \brief Types of file descriptor events */
         enum EventId { EV_NONE=0, 
                        EV_READ=1, EV_PRIO=2, EV_WRITE=4, EV_HUP=8, EV_ERR=16, 
                        EV_ALL=31 };
 
+       /** \brief Template typedef for Callback type
+           
+           This is a template typedef (which does not exist in C++) that is, a template class whose
+           sole member is a typedef symbol defining the callback type given the handle type.
+
+           The Callback is any callable object taking a \c Handle and an \c EventId as argument.
+        */
         template <class Handle>
         struct GenericCallback {
             typedef boost::function<void (typename boost::call_traits<Handle>::param_type,
                                           EventId) > Callback;
         };
-       typedef boost::function<void (EventId)> SimpleCallback;
+       /** \brief Callback type for timer events */
        typedef boost::function<void ()> TimerCallback;
 
         ///////////////////////////////////////////////////////////////////////////
@@ -82,6 +104,17 @@ namespace senf {
         // default destructor
         // no conversion constructors
 
+       /** \brief Return Scheduler instance 
+           
+           This static member is used to access the singleton instance. This member is save to
+           return a correctly initialized Scheduler instance even if called at global construction
+           time
+           
+           \implementation This static member just defines the Scheduler as a static method
+               variable. The C++ standard then provides above guaratee. The instance will be
+               initialized the first time, the code flow passes the variable declaration found in
+               the instance() body.
+        */
         static Scheduler & instance();
 
         ///@}
@@ -90,23 +123,58 @@ namespace senf {
         template <class Handle>
         void add(Handle const & handle, 
                  typename GenericCallback<Handle>::Callback const & cb,
-                 int eventMask = EV_ALL); 
+                 int eventMask = EV_ALL); ///< Add file handle event callback
+                                        /**< add() will add a callback to the Scheduler. The
+                                            callbeck will be called for the given type of event on
+                                            the given  arbitrary file-descriptor or
+                                            handle-like object. If there already is a Callback
+                                            register ed for one of the events requested, the new
+                                            handler will replace the old one.
+                                            \param[in] handle file descriptor or handle providing
+                                                the Handle interface defined above.
+                                            \param[in] cb callback
+                                            \param[in] eventMask arbitrary combination via '|'
+                                                operator of EventId designators. */
        template <class Handle>
-        void remove(Handle const & handle, int eventMask = EV_ALL);
-
-       void timeout(unsigned long timeout, TimerCallback const & cb);
-
-        void process();
-        void terminate();
+        void remove(Handle const & handle, int eventMask = EV_ALL); ///< Remove event callback
+                                        /**< remove() will remove any callback registered for any of
+                                            the given events on the given file descriptor or handle
+                                            like object.
+                                            \param[in] handle file descriptor or handle providing
+                                                the Handle interface defined above.    
+                                            \param[in] eventMask arbitrary combination via '|'
+                                                operator of EventId designators. */
+
+       void timeout(unsigned long timeout, TimerCallback const & cb); ///< Add timeout event
+                                        /**< \param[in] timeout timeout in milliseconds
+                                            \param[in] cb callback to call after \a timeout
+                                                milliseconds 
+                                            \todo Return some kind of handle/pointer and add
+                                                support to update or revoke a timeout */
+
+        void process();                 ///< Event handler main loop
+                                        /**< This member must be called at some time to enter the
+                                            event handler main loop. Only while this function is
+                                            running any events are handled. The call will return
+                                            only, if any callback calls terminate(). */
+        void terminate();               ///< Called by callbacks to terminate the main loop
+                                        /**< This member may be called by any callback to tell the
+                                            main loop to terminate. The main loop will return to
+                                            it's caller after the currently running callback
+                                            returns. */
 
     protected:
 
     private:
+       typedef boost::function<void (EventId)> SimpleCallback;
+
         Scheduler();
        
         void do_add(int fd, SimpleCallback const & cb, int eventMask = EV_ALL);
         void do_remove(int fd, int eventMask = EV_ALL);
 
+       /** \brief Descriptor event specification
+           \internal */
        struct EventSpec 
         {
             SimpleCallback cb_read;
@@ -118,6 +186,8 @@ namespace senf {
             int epollMask() const;
         };
        
+       /** \brief Timer event specification
+           \internal */
        struct TimerSpec
        {
            TimerSpec() : timeout(), cb() {}
@@ -140,13 +210,20 @@ namespace senf {
         bool terminate_;
     };
 
+    /** \brief Default file descriptor accessor
+       
+       retrieve_filehandle() provides the Scheduler with support for explicit file descriptors as
+       file handle argument.
+
+       \relates Scheduler
+     */
     int retrieve_filehandle(int fd);
 
 }
 
 ///////////////////////////////hh.e////////////////////////////////////////
 #include "Scheduler.cci"
-#include "Scheduler.ct"
+//#include "Scheduler.ct"
 #include "Scheduler.cti"
 #endif
 
@@ -154,4 +231,5 @@ namespace senf {
 // Local Variables:
 // mode: c++
 // c-file-style: "senf"
+// fill-column: 100
 // End:
index 04a4f1c..28bf5b6 100644 (file)
@@ -1,8 +1,25 @@
 // $Id$
 //
+// Copyright (C) 2006 Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 // Copyright (C) 2006 
 
-// Definition of non-inline template functions
+/** \file
+    \brief WriteHelper non-inline template implementation */
 
 //#include "WriteHelper.ih"
 
@@ -58,6 +75,7 @@ template <class Handle>
 prefix_ void senf::WriteHelper<Handle>::process(Handle handle,
                                                        senf::Scheduler::EventId event)
 {
+    /** \fixme Move the done() calls to outside the try/catch block */
     try {
        if (event != senf::Scheduler::EV_WRITE)
            throw senf::SystemException(EPIPE);
index 14437e9..4ab3a89 100644 (file)
@@ -1,8 +1,25 @@
 // $Id$
 //
+// Copyright (C) 2006 Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 // Copyright (C) 2006 
 
-// Definition of inline template functions
+/** \file
+    \brief WriteHelper inline template implementation */
 
 //#include "WriteHelper.ih"
 
index f22cbfe..d2c68c1 100644 (file)
@@ -1,7 +1,26 @@
 // $Id$
 //
+// Copyright (C) 2006 Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 // Copyright (C) 2006 
 
+/** \file
+    \brief WriteHelper public header */
+
 #ifndef HH_WriteHelper_
 #define HH_WriteHelper_ 1
 
 
 namespace senf {
 
+    /** \brief Asyncronous writing helper
+       
+       This class provides a simple asyncronous writing facility. This helper will register with
+       the Scheduler to write the requested data. It will stay registered until the data has benen
+       completely sent or some error condition is encountered. As soon as the WriteHelper is done,
+       the callback will be called.
+
+       The WriteHelper accepts the same flexible file handle interfaces as the Scheduler.
+
+       The callback must take a WriteHelper::ptr argument. Using this WriteHelper instance, the
+       callback can access the state information and check the termination status.
 
+       \todo Add additional interface to better access the intermediate status (data sent so far)
+     */
     template <class Handle>
     class WriteHelper
        : public senf::intrusive_refcount
@@ -26,27 +58,39 @@ namespace senf {
         ///////////////////////////////////////////////////////////////////////////
         // Types
 
-       typedef boost::intrusive_ptr<WriteHelper> ptr;
-       typedef boost::function<void (ptr)> Callback;
+       typedef boost::intrusive_ptr<WriteHelper> ptr; ///< Smart pointer type for this class
+       typedef boost::function<void (ptr)> Callback; ///< Callback type
 
         ///////////////////////////////////////////////////////////////////////////
         ///\name Structors and default members
         ///@{
 
        static ptr dispatch(Handle handle, std::string data, Callback callback);
+                                        ///< Register new WriteHelper instance
+                                        /**< The registered callback will be called after all \a
+                                            data has been sent or when some error condition is
+                                            encountered.
+                                            \param[in] handle file descriptor or handle providing
+                                                the Handle interface defined above.
+                                            \param[in] data data to send
+                                            \param[in] cb callback
+                                            \returns smart pointer to new WriteHelper instance */
 
         ///@}
         ///////////////////////////////////////////////////////////////////////////
 
        Handle handle() const;
 
-       std::string const & data() const;
+       std::string const & data() const; ///< Return the data
+                                        /**< After all data has been sent, this member will return
+                                            an empty string. Until then, the complete string will
+                                            be returned. */
 
-       bool complete() const;
-       bool error() const;
-       void throw_error() const;
+       bool complete() const;          ///< Check wether the write has completed successfully
+       bool error() const;             ///< Check for error condition
+       void throw_error() const;       ///< If an error occured, throw it
 
-       void revoke();
+       void revoke();                  ///< Remove the WriteHelper from the scheduler
 
     protected:
 
@@ -78,4 +122,6 @@ namespace senf {
 \f
 // Local Variables:
 // mode: c++
+// c-file-style: "senf"
+// fill-column: 100
 // End:
index 44165b6..62bba29 100644 (file)
@@ -1,8 +1,24 @@
 // $Id$
 //
-// Copyright (C) 2006 
+// Copyright (C) 2006 Stefan Bund <g0dil@senf.berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-// Definition of non-inline non-template functions
+/** \file
+    \brief DaemonTools  non-inline non-template implementation */
 
 #include "DaemonTools.hh"
 //#include "DaemonTools.ih"
index 7fab851..5f20682 100644 (file)
@@ -1,6 +1,46 @@
 // $Id$
 //
-// Copyright (C) 2006 
+// Copyright (C) 2006 Stefan Bund <g0dil@senf.berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+/** \file
+    \brief DaemonTools public header */
+
+/** \defgroup process Process Management
+
+    This collection of utilities provides help in managing daemon processes.
+
+    \idea Add communication between parent and child process to daemonize() and add things like
+       init_done(), failure() etc which allow the daemon process to tell the frontend of successful
+       startup or failure. This proabably means moving all the methods into a DaemonTools class (as
+       statics or via a singleton). This would also allow for automatic pid file creation and
+       removal (remove in global destructor).
+
+    \idea Add a DaemonProcess baseclass whith init() and main() abstract members which wraps the
+       startup process. DaeminProcess::run() would fork, call init(), create a pid file and then
+       call main(). Exceptions during init()'s execution would be passed to the parent
+       process. This is based on the above API.
+    
+    \idea A closeall()/closemost() function which is useful when starting child processes. We'll use
+       getrlimit to now the biggest filehandle and close all of em. closemost() takes a number of
+       file handles as arg and will keep those open.
+
+    \idea We might want to add other oft used utitlities: chroot(), setreuid(), pipes() / IPC ...
+ */
 
 #ifndef HH_DaemonTools_
 #define HH_DaemonTools_ 1
 
 namespace senf {
 
+    /// \addtogroup process
+    /// @{
 
-    void daemonize();
-    void redirect_stdio(std::string const & path = "/dev/null");
+    void daemonize();                   ///< Make the current process a daemon process
+                                        /**< daemonize() will fork, detach from the controlling
+                                            terminal and start a new process group. */
+    void redirect_stdio(std::string const & path = "/dev/null"); ///< Redirect STDIN, STDOUT and STDERR
+                                        /**< All standard file-descriptors will be redirected to the
+                                            given path defaulting to <tt>/dev/null</tg>
+                                            \param[in] path path to redirect to */
 
+    /// @}
 }
 
 ///////////////////////////////hh.e////////////////////////////////////////
@@ -29,4 +77,6 @@ namespace senf {
 \f
 // Local Variables:
 // mode: c++
+// c-file-style: "senf"
+// fill-column: 100
 // End:
index b193e90..50cf427 100644 (file)
@@ -2,3 +2,4 @@
 
 PROJECT_NAME = libUtils
 GENERATE_TAGFILE = doc/Utils.tag
+ALPHABETICAL_INDEX = NO
index 2798216..cc87f61 100644 (file)
@@ -20,7 +20,8 @@
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-// Definition of non-inline non-template functions
+/** \file
+    \brief Exception non-inline non-template implementation */
 
 #include "Exception.hh"
 //#include "Exception.ih"
@@ -34,6 +35,9 @@
 
 prefix_ void senf::SystemException::init()
 {
+    // We normallyl don't want to consume memory in an exception,
+    // however all other solutions to format the message are terribly
+    // ugly (since thay must use a static and shared buffer ...)
     std::stringstream s;
     if (where)
         s << where << ": ";
similarity index 59%
rename from Scheduler/Scheduler.ct
rename to Utils/Exception.cci
index 1df75e3..565ed2e 100644 (file)
@@ -1,9 +1,6 @@
 // $Id$
 //
-// Copyright (C) 2006 
-// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
-// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
-//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+// Copyright (C) 2006 Stefan Bund <g0dil@senf.berlios.de>
 //
 // This program is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-// Definition of non-inline template functions
-
-//#include "Scheduler.ih"
+/** \file
+    \brief Exception inline non-template implementation */
 
 // Custom includes
 
-#define prefix_
-///////////////////////////////ct.p////////////////////////////////////////
+#define prefix_ inline
+///////////////////////////////cci.p///////////////////////////////////////
+
+prefix_  senf::SystemException::SystemException(int err_)
+    : where(0), err(err_) 
+{
+    init(); 
+}
+
+prefix_ senf::SystemException::SystemException(char const * where_, int err_)
+    : where(where_), err(err_) 
+{ 
+    init(); 
+}
+
+prefix_  senf::SystemException::~SystemException()
+    throw()
+{}
 
-///////////////////////////////ct.e////////////////////////////////////////
+///////////////////////////////cci.e///////////////////////////////////////
 #undef prefix_
 
 \f
 // Local Variables:
 // mode: c++
-// c-file-style: "senf"
 // End:
index 7d5dbf1..9efa133 100644 (file)
@@ -20,6 +20,9 @@
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
+/** \file
+    \brief Exception public header */
+
 #ifndef HH_Exception_
 #define HH_Exception_ 1
 
 
 namespace senf {
 
+    /** \brief Exception handling standard UNIX errors (errno)
+
+       This exception is thrown to signal generic errno failuers.
+
+       \todo make where and err accessors and make the member vars private
 
-    struct SystemException : public std::exception
+       \idea Add a template class derived from SystemException which
+       takes the error number as a numeric argument. This allows
+       catching specific errno conditions: ErrnoException<EPIPE> etc.
+       
+       \idea Add a generic error thrower which takes the origin
+       string and errno value as an argument and will throw a
+       corresponding template class instance. This would just be a
+       big switch statement containing all possible errno values,
+       probably created using some makro metaprogramming.
+     */
+    class SystemException : public std::exception
     {
-        explicit SystemException(int err_) : where(0), err(err_) { init(); }
-        SystemException(char const * where_, int err_) : where(where_), err(err_) { init(); }
+    public:
+        explicit SystemException(int err); ///< SystemException without error lokus info
+                                        /**< \param[in] err errror number (the errno value) */
+        SystemException(char const * where, int err); ///< SystemException with error lokus info
+                                        /**< \param[in] where description of error origin
+                                            \param[in] err error number (the errno value) */
 
-        virtual char const * what() const throw();
+        virtual char const * what() const throw(); ///< Return verbose error description
 
-        char const * where;
-        int err;
+        char const * where; ///< Error origin
+        int err; ///< Error number
 
-        virtual ~SystemException() throw() {}
+        virtual ~SystemException() throw();
     private:
         void init();
        std::string buffer_;
@@ -52,7 +74,7 @@ namespace senf {
 }
 
 ///////////////////////////////hh.e////////////////////////////////////////
-//#include "Exception.cci"
+#include "Exception.cci"
 //#include "Exception.ct"
 //#include "Exception.cti"
 #endif
diff --git a/Utils/Mainpage.dox b/Utils/Mainpage.dox
new file mode 100644 (file)
index 0000000..de801f3
--- /dev/null
@@ -0,0 +1,43 @@
+namespace senf {
+
+/** \mainpage The SENF Utilities Library
+
+    The Utilities Library is a collection of independent
+    utilities. We have
+    <dl>
+
+    <dt>SystemException</dt><dd>standard exception for system errors
+    (errno)</dd>
+
+    <dt>\ref time</dt><dd>Very rudimentary microsecond time
+    support</dd>
+    
+    <dt>\ref process</dt><dd>Some simple process management and daemon
+    helpers<?dd>
+    
+    <dt>\ref membind</dt><dd>a simple <a
+    href="http://www.boost.org/libs/bind/bind.html">Boost.Bind</a>
+    extension</dd>
+
+    <dt>intrusive_refcount</dt><dd>mixin to simplify writing classes for
+    use with <a
+    href="http://www.boost.org/libs/smart_ptr/intrusive_ptr.html">boost::intrusive_ptr</a></dd>
+
+    <dt>SafeBool</dt><dd>a mixin class to provide a really safe
+    replacement for <tt>operator bool</tt></dd>
+
+    <dt>prettyName()</dt><dd>an interface to the C++ demangler of g++
+    to get formated type names from typeinfo objects</dd>
+
+    </dl>
+ */
+
+}
+
+\f
+// Local Variables:
+// mode: c++
+// mode: flyspell
+// mode: auto-fill
+// ispell-local-dictionary: "american"
+// End:
index 5006c50..23d2a99 100644 (file)
@@ -1,8 +1,24 @@
 // $Id$
 //
-// Copyright (C) 2006 
+// Copyright (C) 2006 Stefan Bund <g0dil@senf.berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-// Definition of non-inline non-template functions
+/** \file
+    \brief MicroTime non-inline non-template implementation */
 
 #include "MicroTime.hh"
 //#include "MicroTime.ih"
index d4495e1..0d04900 100644 (file)
@@ -1,6 +1,39 @@
 // $Id$
 //
-// Copyright (C) 2006 
+// Copyright (C) 2006 Stefan Bund <g0dil@senf.berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+/** \file
+    \brief MicroTime public header */
+
+/** \defgroup time Microseconds Time
+
+    MicroTime provides extremely rudimentary support for a time data
+    type precise to 10<sup>-6</sup> seconds. Up to now, the only
+    supported members are the datatype (which just uses a 64 bit
+    integer) and the now() function to get the current UTC time in
+    microsecods since the Epoch.
+    
+    \idea This thing only exists as a quick hack. We can probably make
+       use of Boost.Time or some such thing so it probably does not
+       make sense to extend this further. We should however check the
+       performance of Boost.Time since this is used heavily in the
+       Scheduler.
+ */
 
 #ifndef HH_MicroTime_
 #define HH_MicroTime_ 1
 ///////////////////////////////hh.p////////////////////////////////////////
 
 namespace senf {
+    
+    /// \addtogroup time
+    /// @{
 
+    typedef boost::uint64_t MicroTime; ///< Microsecond accurent time datatype
 
-    typedef boost::uint64_t MicroTime;
+    MicroTime now(); ///< Get current UTC time with microsecond accuracy
 
-    MicroTime now();
+    /// @}
 
 }
 
index 43e317b..68b0ffc 100644 (file)
 
 namespace senf {
 
-    
-    // This is a direct copy of a safe bool solution by Bjorn Karlsson 
-    // from http://www.artima.com/cppsource/safebool.html
-    //
-    // Usage:
-    //    class TestableWithVirtual 
-    //        : public safe_bool<> 
-    //    {
-    //    protected:
-    //        bool boolean_test() const 
-    //        {
-    //            // Perform Boolean logic here
-    //        }
-    //    };
-    //
-    //    class TestableWithoutVirtual 
-    //        : public safe_bool <TestableWithoutVirtual> 
-    //    {
-    //    public:
-    //        bool boolean_test() const 
-    //        {
-    //            // Perform Boolean logic here
-    //        }
-    //    };
-
+    /** \brief internal SafeBool base class
+       \internal
+     */
     class SafeBoolBase 
     {
     protected:
        typedef void (SafeBoolBase::*bool_type)() const;
        void this_type_does_not_support_comparisons() const;
 
+       // Just here to make them protected ...
+
        SafeBoolBase();
        SafeBoolBase(const SafeBoolBase&);
        SafeBoolBase& operator=(const SafeBoolBase&);
        ~SafeBoolBase();
     };
 
-    template <typename T=void> 
+    /** \brief Mixin class for safe boolean conversion support
+       
+       This is a direct yet simplified copy of a safe bool solution
+       by Bjorn Karlsson from
+       http://www.artima.com/cppsource/safebool.html
+
+       This mixin provides the client class with safe boolean
+       testing. It is a safe replacement for <tt>operator
+       bool</tt>. <tt>operator bool</tt> is problematic since \c bool
+       is an integer type. This conversion operator makes the class
+       usable in any numeric context, which can be quite
+       dangerous. The <tt>operator void *</tt> solution is much
+       better in this respect but still allows two instances of any
+       class having such a <tt>void *</tt> conversion to be compared
+       for equality. This again will produce absolutely unexpected
+       results since it will not check wethere the objects are
+       identical, it will only check, that both return the same
+       boolean state.
+
+       This solutions solves all these problems by returning a
+       pointer-to-member which cannot be converted to any other
+       type. By providing explicit implementations of \c operator==
+       and \c operator!= which fail in an obvious way at compile
+       time, this hazard is removed.
+
+       To make a class boolean testable, just inherit from the mixin
+       and implement \c boolean_test:
+       
+       \code
+        class Testable 
+            : public SafeBool<Testable> 
+        {
+        public:
+            bool boolean_test() const 
+            {
+                // Perform Boolean logic here
+            }
+        };
+
+       Testable t = ...;
+
+       if (t) {
+          ...
+       }
+       \endcode
+
+       \todo Either rename intrusive_refcount to IntrusiveRefcount or
+       SafeBool to safe_bool (I tend to the latter ...)
+     */
+    template <typename T> 
     class SafeBool 
        : public SafeBoolBase 
     {
index 9f0bd6a..296f22b 100644 (file)
@@ -20,7 +20,8 @@
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-// Definition of non-inline non-template functions
+/** \file
+    \brief TypeInfo non-inline non-template implementation */
 
 #include "TypeInfo.hh"
 //#include "TypeInfo.ih"
index 98c3b38..8f8ca97 100644 (file)
@@ -20,6 +20,9 @@
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
+/** \file
+    \brief TypeInfo public header */
+
 #ifndef HH_TypeInfo_
 #define HH_TypeInfo_ 1
 
 
 namespace senf {
 
+    /** \brief Try to return readable type for given type_info
+       
+       This function will try to return a demangled type name for the
+       given type_info object. If the demangling fails, the possibly
+       mangled name (type->name()) will be returned.
+
+       This function depends on the liberty library provided by the
+       linux binutils or binutils-dev packages. It also depends on an
+       internal header file. If the API should change, this header
+       file (which resides in impl/demangle.h) must be updated from
+       the binutils sources.
 
+       \param[in] type type_info object
+       \returns type name, possibly demangled
+     */
     std::string prettyName(std::type_info const & type);
 
 }
index 3318a4d..39f8776 100644 (file)
@@ -20,7 +20,8 @@
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-// Definition of inline non-template functions
+/** \file
+    \brief intrusive_refcount inline non-template implementation */
 
 //#include "intrusive_refcount.ih"
 
index 754686d..36a7564 100644 (file)
@@ -20,6 +20,9 @@
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
+/** \file
+    \brief intrusive_refcount public header */
+
 #ifndef HH_intrusive_refcount_
 #define HH_intrusive_refcount_ 1
 
 
 namespace senf {
 
+    /** \brief Reference count mixin for intrusive_ptr
+
+       This class provides a simple internally managed refcount and supplies the <a
+       href="http://www.boost.org/libs/smart_ptr/intrusive_ptr.html">boost::intrusive_ptr</a>
+       required interface. To make a class compatible with \c boost::intrusive_ptr, just derive
+       publicly from intrusive_refcount.
 
-    /** \brief
+       Two additional benifits of using intrusive_refcount are
+       \li The object can access it's own refcount
+       \li It is valid and safe to convert a plain object pointer to an intrusive_ptr at any time
+           (not only after new)
      */
     class intrusive_refcount
         : public boost::noncopyable
     {
     public:
-        typedef unsigned refcount_t;
+        typedef unsigned refcount_t;    ///< reference count type
 
         virtual ~intrusive_refcount();
 
-        refcount_t refcount();
-        bool is_shared();
+        refcount_t refcount();          ///< current refcount
+        bool is_shared();               ///< return \c true if refcount() > 1
 
     protected:
         intrusive_refcount();
@@ -72,4 +84,5 @@ namespace senf {
 // Local Variables:
 // mode: c++
 // c-file-style: "senf"
+// fill-column: 100
 // End:
index bc9b30d..b876890 100644 (file)
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
+/** \file
+    \brief membind  public header */
+
+/** \defgroup membind Bound Member Functions
+
+    The membind() family of function templates simplifies the creation
+    of simple bound member function pointers:
+
+    \code
+      struct Foo {
+          int test(int x);
+      };
+
+      Foo * foo = ...; 
+      boost::function<int (int)> f = senf::membind(&Foo::test,foo);
+      int rv = f(1); // Calls foo->test(1)
+    \endcode
+
+    \idea Make the \a ob argument type an additional P template
+    parameter (using call_traits for the exact arg type? Probably
+    we'll get deduction problems then) . The only operation this
+    object musst suppoprt is ob->*fn. This would allow the use of
+    smart pointers. We should keep the T & version to still support
+    ob.*fn use.
+ */
+
 #ifndef HH_membind_
 #define HH_membind_ 1
 
@@ -31,7 +57,6 @@
 
 namespace senf {
 
-
 #define scOBTYPE T *
 #include "Utils/impl/membind.hh"
 #undef scOBTYPE
@@ -40,6 +65,28 @@ namespace senf {
 #include "Utils/impl/membind.hh"
 #undef scOBTYPE
 
+#ifdef DOXYGEN
+
+    /// \addtogroup membind
+    /// @{
+
+    /** \brief Build bound member function object
+
+       membind() supports up to 9 function parameters (represented as
+       \a Args here). The \a ob argument can be either a pointer or a
+       reference to \a T
+       \param[in] fn member function pointer
+       \param[in] ob object instance to bind this pointer to
+       \returns Boost.Function object representing a bound call of \a
+           fn on \a ob
+     */
+    template <typename R, typename T, typename Args>
+    boost::function<R (Args)> membind(R (T::* fn)( Args ), T * ob);
+
+    /// @}
+
+#endif
+
 }
 
 ///////////////////////////////hh.e////////////////////////////////////////
index 0fd65d3..eb9214d 100755 (executable)
@@ -1,8 +1,11 @@
 #!/usr/bin/perl -n
 
-if (/^\s*\\code\s*$/ .. /\\endcode/) {
-    $i=length((/^(\s*)/)[0]) if /^\s*\\code\s*$/;
-    print substr($_,$i);
+s/\s*$//;
+while (s/\t/' 'x(8-length($`)%8)/e) {}
+
+if (/^\s*\\code$/ .. /\\endcode/ && !/^$/) {
+    $i=length($1) if /^(\s*)\\code$/;
+    print substr($_,$i),"\n";
 } else {
-    print;
+    print $_,"\n";
 }
index 740d06b..270f997 100644 (file)
@@ -188,7 +188,7 @@ dl.bug, dl.fixme, dl.todo, dl.idea {
 dl.xref-bug, dl.xref-fix, dl.xref-todo, dl.xref-idea { 
        border: 1px solid #CC8888;
        padding: 2px 3px;
-       margin: 4px 0;
+       margin: 4px 8px 4px 2px;
        background-color: #FFEEEE;
        color: #666666;
        font-size: 9px;