-// 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
// Custom includes
#include <memory>
+#include <vector>
#include <boost/utility.hpp>
+#include <boost/type_traits/is_base_of.hpp>
+#include <boost/type_traits/has_trivial_constructor.hpp>
+#include <boost/type_traits/has_trivial_destructor.hpp>
+#include <boost/static_assert.hpp>
#include "../Utils/pool_alloc_mixin.hh"
#include "PacketTypes.hh"
+#include "../Utils/singleton.hh"
//#include "PacketImpl.mpp"
///////////////////////////////hh.p////////////////////////////////////////
namespace senf {
+
+ /** \brief Marker base-class for complex annotations
+
+ This class is used as a base class to mark an annotation type as complex. A complex
+ annotation will have it's constructor/destructor called. Non-complex annotations will not
+ have their constructor called, they will be zero initialized. The destructor of non-complex
+ annotations is never called.
+
+ An annotation must be marked as complex if it is not <a
+ href="http://en.wikipedia.org/wiki/Plain_Old_Data_Structures">POD</a>. Simplified, an
+ annotation must be marked as ComplexAnnotation, if
+
+ \li it has a (user defined) constructor or destructor
+ \li it has any data members which have (user defined) constructors or destructors
+
+ \see \ref packet_usage_annotation
+ */
+ struct ComplexAnnotation {};
+
namespace detail {
-
+
+ struct AnnotationP
+ {
+ virtual ~AnnotationP();
+ };
+
+ template <class Annotation>
+ struct TAnnotationP
+ : public AnnotationP
+ {
+ Annotation annotation;
+ };
+
+ union AnnotationEntry {
+ AnnotationP * p;
+ unsigned long long i;
+ };
+
+ struct AnnotationIndexerBase
+ {
+ static unsigned maxAnnotations;
+ static std::vector<bool> & small();
+ };
+
+ template <class Annotation>
+ struct AnnotationIndexer
+ : public senf::singleton< AnnotationIndexer<Annotation> >,
+ public AnnotationIndexerBase
+ {
+ AnnotationIndexer();
+ unsigned index_;
+ static unsigned index();
+ static bool const Complex = boost::is_base_of<ComplexAnnotation, Annotation>::value;
+ static bool const Small = (sizeof(Annotation) <= sizeof(AnnotationEntry) && ! Complex);
+
+# ifdef BOOST_HAS_TYPE_TRAITS_INTRINSICS
+
+ BOOST_STATIC_ASSERT(( (boost::has_trivial_constructor<Annotation>::value
+ && boost::has_trivial_destructor<Annotation>::value)
+ || Complex ));
+
+# endif
+ };
+
+ template <class Annotation, bool Small = AnnotationIndexer<Annotation>::Small>
+ struct GetAnnotation
+ {
+ static Annotation & get(AnnotationEntry & e);
+ };
+
+ template <class Annotation>
+ struct GetAnnotation<Annotation, true>
+ {
+ static Annotation & get(AnnotationEntry & e);
+ };
+
/** \brief Internal: Packet data storage
-
+
\internal
This is the class holding the packet data and the interpreter chain. All manipulations of
PacketImpl will update the interpreters (that is the vector indices stored therein) whenever
the data is changed.
*/
- class PacketImpl
+ class PacketImpl
: boost::noncopyable,
public pool_alloc_mixin<PacketImpl>
{
~PacketImpl();
// rerference/memory management
-
+
void add_ref(refcount_t n=1);
void release(refcount_t n=1);
refcount_t refcount() const;
void erase(PacketData * self, iterator first, iterator last);
void clear(PacketData * self);
+ // Annotations
+ template <class Annotation>
+ Annotation & annotation();
+
/** \brief Internal: Keep PacketImpl instance alive
\internal
refcount_t refcount_;
raw_container data_;
interpreter_list interpreters_;
+
+ typedef std::vector<AnnotationEntry> Annotations;
+ Annotations annotations_;
void eraseInterpreters(interpreter_list::iterator b, interpreter_list::iterator e);
- void updateIterators(PacketData * self, iterator pos, difference_type n);
+ void updateIterators(PacketData * self, difference_type pos, difference_type n);
};
}}
///////////////////////////////hh.e////////////////////////////////////////
#endif
-#if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_PacketImpl_i_)
+#if !defined(HH_Packets__decls_) && !defined(HH_PacketImpl_i_)
#define HH_PacketImpl_i_
#include "PacketImpl.cci"
//#include "PacketImpl.ct"