Listing 3

#include <iostream>
#include <vector>
#include <list>
using namespace std;
#include "timeit.hpp"

struct Point {
  int mx, my;
  Point() { mx = 0; my = 0; };
  Point(int x, int y) { mx = x; my = y; };
  Point Plus(const Point& x) { return Point(x.mx + mx, x.my + my); };
  void Draw() const { cout << "x: " << mx << " y: " << my; };
  void MoveTo(const Point& x) { mx = x.mx; my = x.my;  };
};
#include "shapes.hpp"
struct Circle {
  Circle() { mSize = 0; };
  void Draw() const { /* noop */ };
  void MoveTo(const Point& x) { mCenter.MoveTo(x); Draw(); };
  void MoveBy(const Point& x) { MoveTo(GetPos().Plus(x)); };
  Point GetPos() const { return mCenter; };
  void SetSize(int x) { mSize = x; };
  int GetSize() const { return mSize; };
  Point mCenter;
  int mSize;
};
struct AbcDrawable {
  virtual void Draw() const = 0;
};
struct AbcPosition {
  virtual Point GetPos() const = 0;
};
struct AbcMoveable {
  virtual void MoveTo(const Point& x) = 0;
  virtual void MoveBy(const Point& x) = 0;
};
struct AbcSizeable {
  virtual void SetSize(int x) = 0;
  virtual int GetSize() const = 0;
};
struct AbcShape : public AbcDrawable, public AbcPosition, 
                                 public AbcMoveable, public AbcSizeable {
};
struct NaiveCircle : public AbcShape {
  NaiveCircle() { mSize = 0; };
  void Draw() const { /* noop */ };
  void MoveTo(const Point& x) { mCenter.MoveTo(x); Draw(); };
  void MoveBy(const Point& x) { MoveTo(GetPos().Plus(x)); };
  Point GetPos() const { return mCenter; };
  void SetSize(int x) { mSize = x; };
  int GetSize() const { return mSize; };
  Point mCenter;
  int mSize;
};
template<typename T> void RunTest(T x, const char* s) {
  const int ITERS = 5000000;
  Point pt(0, 0);
  cout << "sizeof(" << s << ") = " << sizeof(T) << endl;
  cout << "timing " << ITERS << " calls to " << s << "::MoveBy() ... ";
  TimeIt t;
  x.MoveTo(pt);
  for (int i=0; i < ITERS; i++)  {
    x.MoveBy(Point(i, i));
  }
};
int main()
{
  Circle c1;
  NaiveCircle c2;

  RunTest<IShape>(c1, "IShape");
  RunTest<AbcShape&>(c2, "AbcShape&");
  RunTest<IMoveable>(c1, "IMoveable");
  RunTest<AbcMoveable&>(c2, "AbcMoveable&");
  RunTest<Circle&>(c1, "Circle&");
  RunTest<NaiveCircle&>(c2, "NaiveCircle&");
  RunTest<Circle>(c1, "Circle");
  RunTest<NaiveCircle>(c2, "NaiveCircle");

  cin.get();
  return 0;
}