merge
authorGustavo J. A. M. Carneiro <gjc@inescporto.pt>
Thu, 14 Jun 2007 12:55:24 +0100
changeset 768 28b9c546ea52
parent 767 c36570ed4f5e (current diff)
parent 766 aa1dff7879c8 (diff)
child 769 b4c78b6bdbd1
merge
--- a/SConstruct	Thu Jun 14 10:41:47 2007 +0200
+++ b/SConstruct	Thu Jun 14 12:55:24 2007 +0100
@@ -411,6 +411,12 @@
 sample_trace.set_executable()
 sample_trace.add_source('main-trace.cc')
 
+sample_query_interface = build.Ns3Module('sample-query-interface', 'samples')
+ns3.add(sample_query_interface)
+sample_query_interface.add_dep('common')
+sample_query_interface.set_executable()
+sample_query_interface.add_source('main-query-interface.cc')
+
 sample_simu = build.Ns3Module('sample-simulator', 'samples')
 ns3.add(sample_simu)
 sample_simu.set_executable()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/main-query-interface.cc	Thu Jun 14 12:55:24 2007 +0100
@@ -0,0 +1,280 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 University of Washington
+ * Authors:  Tom Henderson, Craig Dowell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * 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
+ */
+
+#include "ns3/debug.h"
+#include "ns3/object.h"
+#include "ns3/component-manager.h"
+
+using namespace ns3;
+
+//
+// This sample file shows examples of how to use QueryInterface.
+//
+// QueryInterface is a templated method of class Object, defined in 
+// src/core/object.h.  ns-3 objects that derive from class Object
+// can have QueryInterface invoked on them.
+//
+// QueryInterface is a type-safe way to ask an object, at run-time, 
+// "Do you support the interface identified by the given InterfaceId?"  
+// It avoids deprecated techniques of having to downcast pointers to 
+// an object to ask questions about its type.  One or more interfaces
+// may be associated with a given object.
+// 
+// QueryInterface is of most use when working with base class
+// pointers of objects that may be subclassed.  For instance,
+// one may have a pointer to a Node, but not know whether it has
+// an IPv4 stack.  Another example might be to determine whether
+// a Node has an EnergyModel, to which calls to decrement energy
+// from the node's battery might be made.
+//
+
+
+//
+// Object is the base class for ns-3 node-related objects used at 
+// the public API.  Object provides reference counting implementations
+// and the QueryInterface.
+// 
+// A common design paradigm for an ns-3 node object, such as a Queue,
+// is that we provide an abstract base class that inherits from
+// Object.  This class is assigned an interface ID (iid) and 
+// contains the basic API for objects in this class and subclasses.
+// This base class is specialized to provide implementations of
+// the object in question (such as a DropTailQueue).
+// 
+// The design pattern commonly used is known as the "non-virtual
+// public interface" pattern, whereby the public API for this
+// object is a set of public non-virtual functions that forward
+// to private virtual functions.  The forwarding functions can
+// impose pre- and post-conditions on the forwarding call at
+// the base class level.
+// 
+// We'll call this base class "AnInterface" in the example below.
+//
+// 
+class AnInterface : public Object
+{
+public:
+  static const InterfaceId iid;
+  void methodA (void);
+private:
+  virtual void domethodA (void) = 0;
+};
+
+void
+AnInterface::methodA (void)
+{
+  // pre-dispatch asserts
+   NS_DEBUG_UNCOND("AnInterface pre-condition::methodA");
+  domethodA ();
+   NS_DEBUG_UNCOND("AnInterface post-condition::methodA\n");
+  // post-dispatch asserts
+}
+
+//
+// The below assignment assigns the InterfaceId of the class AnInterface,
+// and declares that the parent iid is that of class Object.
+//
+const InterfaceId AnInterface::iid = MakeInterfaceId ("AnInterface", Object::iid);
+
+//
+// AnImplementation is an implementation of the abstract base class
+// defined above. It provides implementation for the virtual functions 
+// in the base class.  It defines one ClassId for each constructor, 
+// and can also provide an interface itself (in this example, 
+// a methodImpl is available)
+// 
+class AnImplementation : public AnInterface
+{
+public:
+  static const InterfaceId iid;
+  static const ClassId cid;
+
+  AnImplementation ();
+  void methodImpl (void);
+private:
+  virtual void domethodA (void);
+};
+
+void
+AnImplementation::methodImpl (void)
+{
+   NS_DEBUG_UNCOND("AnImplementation::methodImpl\n");
+}
+
+
+AnImplementation::AnImplementation (void)
+{
+  // enable our interface
+  SetInterfaceId (AnImplementation::iid);
+}
+
+void
+AnImplementation::domethodA () 
+{
+   NS_DEBUG_UNCOND("AnImplementation::domethodA");
+}
+
+//
+// The below assignment assigns the InterfaceId of the class AnImplementation,
+// and declares that the parent iid is that of class Object.
+//
+const InterfaceId AnImplementation::iid = 
+  MakeInterfaceId ("AnImplementation", AnInterface::iid);
+
+//
+// The next few lines are used by the component manager.  They
+// state that the component manager can create a new object 
+// AnImplementation and return an interface corresponding to 
+// the AnImplementation iid.
+//
+const ClassId AnImplementation::cid = 
+  MakeClassId<AnImplementation> 
+  ("AnImplementation", AnImplementation::iid);
+
+
+//
+// Extending interfaces
+// ==================
+// What if AnInterface doesn't provide enough API for your
+// object type?
+// - if you aren't concerned about backward compatibility and
+//   don't mind recompiling, you just add new methods to AnInterface
+//   and recompile.
+// - if you want to address backward compatibiliy, or allow part
+//   of the system to use the old interface, you have to do more.
+//   You have to declare a new interface with the new functionality.
+//
+
+class AnExtendedInterface : public AnInterface
+{
+public:
+  static const InterfaceId iid;
+  void methodB (void);
+private:
+  virtual void domethodB (void) = 0;
+};
+
+const InterfaceId AnExtendedInterface::iid = 
+  MakeInterfaceId ("AnExtendedInterface", AnInterface::iid);
+
+//
+// Then you need provide an implementation for the virtual 
+// methods.  If you are providing a new implementation for 
+// everything, the answer is straightforward
+//
+
+class ANewImplementation : public AnExtendedInterface
+{
+public:
+  static const InterfaceId iid;
+  static const ClassId cid;
+
+  ANewImplementation ();
+  void methodImpl (void);
+private:
+  virtual void domethodA (void) { /* new-implementation-behavior ();  */}
+  virtual void domethodB (void) { /* new-implementation-behavior (); */}
+};
+
+ANewImplementation::ANewImplementation (void)
+{
+  // enable our interface
+  SetInterfaceId (ANewImplementation::iid);
+}
+
+void
+ANewImplementation::methodImpl (void)
+{
+   NS_DEBUG_UNCOND("ANewImplementation::methodImpl\n");
+}
+
+const InterfaceId ANewImplementation::iid = 
+  MakeInterfaceId ("ANewImplementation", AnExtendedInterface::iid);
+
+//
+// If you want to extend an existing implementation, you can use 
+// the existing class to instantiate an implementation of its 
+// methods (hasa) and do the following if you can use stuff from 
+// the existing class.
+//
+
+class AnExtendedImplementation : public AnExtendedInterface
+{
+public:
+  static const InterfaceId iid;
+  static const ClassId cid;
+
+  AnExtendedImplementation ();
+  void methodImpl (void) { /* pImpl->methodImpl (); */ }
+  void methodExtendedImpl (void);
+private:
+  virtual void domethodA (void) { /* new-implementation-behavior (); */}
+  virtual void domethodB (void) { /* new-implementation-behavior (); */}
+  Ptr<AnImplementation> pImpl;
+};
+
+AnExtendedImplementation::AnExtendedImplementation (void)
+{
+  pImpl = Create<AnImplementation> (); 
+  SetInterfaceId (AnExtendedImplementation::iid);
+}
+
+void
+AnExtendedImplementation::methodExtendedImpl (void)
+{
+   NS_DEBUG_UNCOND("AnExtendedImplementation::methodExtendedImpl\n");
+}
+
+const InterfaceId AnExtendedImplementation::iid = 
+  MakeInterfaceId ("AnExtendedImplementation", AnExtendedInterface::iid);
+
+//
+// Inheriting from an existing implementation (isa) and an extended
+// interface is tricky, because of the diamond multiple inheritance
+// problem.  If the pImpl method above is not desirable, it may
+// be that the implementation extension could be aggregated.
+// 
+// The extension will not have access to the base implementation,
+// so this design pattern may be more appropriate if the extension
+// is very modular (e.g., add an EnergyModel to a wireless interface)
+//
+// EXAMPLE NOT YET PROVIDED
+
+int main (int argc, char *argv[])
+{
+
+  Ptr<AnInterface> aBase = ComponentManager::Create<AnImplementation> 
+    (AnImplementation::cid, AnInterface::iid);
+  NS_ASSERT (aBase != 0);
+
+  aBase->methodA ();
+  //aBase->methodImpl (); // XXX won't compile, aBase not right ptr type
+  
+  Ptr<AnImplementation> aBaseImplPtr = 
+    aBase-> QueryInterface<AnImplementation> (AnImplementation::iid);
+  aBaseImplPtr->methodImpl ();
+  aBaseImplPtr->methodA();
+
+  // Test symmetric property of QueryInterface 
+  Ptr<AnInterface> aBase2 = 
+    aBaseImplPtr-> QueryInterface<AnInterface> (AnInterface::iid);
+  aBase2->methodA ();
+
+  return 0;
+}
--- a/src/simulator/cairo-wideint.c	Thu Jun 14 10:41:47 2007 +0200
+++ b/src/simulator/cairo-wideint.c	Thu Jun 14 12:55:24 2007 +0100
@@ -786,7 +786,7 @@
 	nonneg_den = _cairo_int64_negate (den);
 
     uqr = _cairo_uint_96by64_32x64_divrem (num, nonneg_den);
-    if (_cairo_uint64_eq (uqr.rem, nonneg_den)) {
+    if (_cairo_uint64_eq (uqr.rem, _cairo_int64_to_uint64 (nonneg_den))) {
 	/* bail on overflow. */
 	qr.quo = _cairo_uint32s_to_uint64 (0x7FFFFFFF, -1U);;
 	qr.rem = den;
--- a/wscript	Thu Jun 14 10:41:47 2007 +0200
+++ b/wscript	Thu Jun 14 12:55:24 2007 +0100
@@ -79,6 +79,7 @@
     conf.setenv(variant_name)
 
     variant_env.append_value('CXXDEFINES', 'RUN_SELF_TESTS')
+    variant_env.append_value('CXXFLAGS', ['-Wall', '-Werror'])
     if 'debug' in Params.g_options.debug_level.lower():
         variant_env.append_value('CXXDEFINES', 'NS3_DEBUG_ENABLE')
         variant_env.append_value('CXXDEFINES', 'NS3_ASSERT_ENABLE')