Packets: Fix VariantParser invalid parser access bug
[senf.git] / Utils / IteratorTraits.hh
index 6bc00bf..bb2fa5a 100644 (file)
@@ -1,6 +1,8 @@
-// Copyright (C) 2007 
-// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
-// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+// $Id$
+//
+// Copyright (C) 2007
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
 //     Stefan Bund <g0dil@berlios.de>
 //
 // This program is free software; you can redistribute it and/or modify
 /** \file
     \brief IteratorTraits public header */
 
-#ifndef HH_IteratorTraits_
-#define HH_IteratorTraits_ 1
+#ifndef HH_SENF_Utils_IteratorTraits_
+#define HH_SENF_Utils_IteratorTraits_ 1
 
 // Custom includes
+#include <boost/type_traits/integral_constant.hpp>
 #include <vector>
 #include <string>
 
@@ -36,55 +39,68 @@ namespace senf {
 // The following is *not* standard mandated but it *is* mandated by TR1 and I know of no
 // implementation for which this is not correct
 
-#define SENF_VECTOR_IS_CONTIGUOUS 1
-#define SENF_STRING_IS_CONTIGUOUS 1
-    
     /** \brief Check for contiguous mutable storage
 
         This type trait returns \c true, if \a RandomAccessIterator is an iterator into a contiguous
         storage area which may be written to. If this is the case, some algorithms may be optimized
         by directly modifying the underlying storage instead of relying on the STL interface.
+
+        \code
+        // Generic algorithm
+        template <class Iterator>
+        void do(Iterator i, boost::false_type)
+        {
+            // Access the iterator 'i' via the standard STL interface
+        }
+
+        template<class Iterator>
+        void do(Iterator i, boost::true_type) 
+        {
+            typename Iterator::pointer p (senf::storage_iterator(i));
+            // Manipulate the container by manipulating the data pointed at via 'p'
+        }
+
+        template <class Iterator>
+        void foo(Iterator i)
+        {
+            // ...
+            do( i, senf::contiguous_storage_iterator<Iterator>() );
+            // ...
+        }
+        \endcode
+
+        Thie \ref senf::storage_iterator helper function will convert an iterator to a pointer to
+        the same element the iterator is referencing.
         
-        This trait is predefined to return \c true for pointers and for the iterators of \c
-        std::vector and \c std::basic_string (and so for \c std::string and \c std::wstring). This
-        is \e not required by the current standard. It is however required for \c std::vector in the
-        first corrigendum to the standard, TR1. Furthermore almost all implementations for \c
-        std::vector do follow this approach. 
-
-        For \c std::string the case is different, there are libraries which use reference counting
-        and shared ownership for strings, however no library with which SENF has been tested to date
-        has strings of this variety. If SENF is used with such a standard library implementation,
-        this header has to be adjysted to define the preprocessor symbol \c
-        SENF_STRING_IS_CONTIGUOUS accordingly.
+        This trait will return \c true for pointers. Additonally it should be configured to return
+        true for all standard containers which obey above implementation restrictions. This
+        typically includes \c std::vector and \c std::basic_string.
+
+        To do so, the template must be specialized for those containers \c iterator type. If
+        compiling with g++, this is implemented in \ref IteratorTraits.ih. This file should be
+        extended for further compilers or STL implementations if needed.
      */
     template <class RandomAccessIterator>
     struct contiguous_storage_iterator
         : public boost::false_type
     {};
 
+    /** \brief Check for contiguous mutable storage. Pointer specialization
+
+        See \ref contiguous_storage_iterator.
+     */
     template <class T>
     struct contiguous_storage_iterator<T *>
         : public boost::true_type
     {};
 
-#if defined(SENF_VECTOR_IS_CONTIGUOUS)
-    template <class T, class Alloc>
-    struct contiguous_storage_iterator< typename std::vector<T,Alloc>::iterator >
-        : public boost::true_type
-    {};
-#endif
-
-#if defined(SENF_STRING_IS_CONTIGUOUS)
-    template <class CharT, class Traits, class Alloc>
-    struct contiguous_storage_iterator< typename std::basic_string<CharT, Traits, Alloc>::iterator >
-        : public boost::true_type
-    {};
-#endif
-
     /** \brief Convert contiguous storage iterator to pointer
         
         storage_iterator will convert a contiguous storage iterator into a pointer to the same
         element in the container. This allows to directly access the containers storage.
+
+        \warning This conversion is only safe if \ref contiguous_storage_iterator<Iterator>::value
+            is \c true for the given iterator type !
      */
     template <class Iterator>
     typename std::iterator_traits<Iterator>::pointer storage_iterator(Iterator i);
@@ -94,7 +110,8 @@ namespace senf {
 ///////////////////////////////hh.e////////////////////////////////////////
 //#include "IteratorTraits.cci"
 //#include "IteratorTraits.ct"
-//#include "IteratorTraits.cti"
+#include "IteratorTraits.cti"
+#include "IteratorTraits.ih"
 #endif
 
 \f
@@ -104,4 +121,6 @@ namespace senf {
 // c-file-style: "senf"
 // indent-tabs-mode: nil
 // ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// comment-column: 40
 // End: