From e38244e7c0af8a70067535b9ba65a5fe63557d5d Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Wed, 13 Jun 2007 18:34:05 +0100 Subject: [PATCH 1/3] WAF: add -Wall and -Werror to CXXFLAGS, like in the SCons build. --- wscript | 1 + 1 file changed, 1 insertion(+) diff --git a/wscript b/wscript index 75bca783c..779c3c136 100644 --- a/wscript +++ b/wscript @@ -79,6 +79,7 @@ def configure(conf): 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') From 50037ae6112cec74ca395829e54f6d0c5b467e6c Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Wed, 13 Jun 2007 18:40:38 +0100 Subject: [PATCH 2/3] Fix compilier warning/error: src/simulator/cairo-wideint.c:789: warning: comparison between signed and unsigned integer expressions. --- src/simulator/cairo-wideint.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/simulator/cairo-wideint.c b/src/simulator/cairo-wideint.c index 354183fe7..1b2ffe1b4 100644 --- a/src/simulator/cairo-wideint.c +++ b/src/simulator/cairo-wideint.c @@ -786,7 +786,7 @@ _cairo_int_96by64_32x64_divrem (cairo_int128_t num, cairo_int64_t den) 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; From cdf13df87d8561868706926386817f4d1d0ab431 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Wed, 13 Jun 2007 23:13:21 -0700 Subject: [PATCH 3/3] Add main-query-interface.cc sample file --- SConstruct | 6 + samples/main-query-interface.cc | 280 ++++++++++++++++++++++++++++++++ 2 files changed, 286 insertions(+) create mode 100644 samples/main-query-interface.cc diff --git a/SConstruct b/SConstruct index 210ebca0b..44f168c6b 100644 --- a/SConstruct +++ b/SConstruct @@ -411,6 +411,12 @@ sample_trace.add_dep('common') 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() diff --git a/samples/main-query-interface.cc b/samples/main-query-interface.cc new file mode 100644 index 000000000..20da36ff3 --- /dev/null +++ b/samples/main-query-interface.cc @@ -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::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 pImpl; +}; + +AnExtendedImplementation::AnExtendedImplementation (void) +{ + pImpl = Create (); + 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 aBase = ComponentManager::Create + (AnImplementation::cid, AnInterface::iid); + NS_ASSERT (aBase != 0); + + aBase->methodA (); + //aBase->methodImpl (); // XXX won't compile, aBase not right ptr type + + Ptr aBaseImplPtr = + aBase-> QueryInterface (AnImplementation::iid); + aBaseImplPtr->methodImpl (); + aBaseImplPtr->methodA(); + + // Test symmetric property of QueryInterface + Ptr aBase2 = + aBaseImplPtr-> QueryInterface (AnInterface::iid); + aBase2->methodA (); + + return 0; +}