


#include <cstdio>
#include <vector>

using namespace std;


#include "bnf_ptr.hpp"

// 複数回インクルードしても大丈夫だよね？
#include "bnf_ptr.hpp"


using namespace bnf;


static int objcount = 0;

struct MyObj
{
  MyObj()
  {
    objcount++;
  }
  
  virtual ~MyObj()
  {
    objcount--;
  }

private:
  // コピーコンストラクタ使用禁止
  MyObj(const MyObj& another) { }
};

typedef Ptr<MyObj> MyObjPtr;

MyObjPtr createMyObj()
{
  return new MyObj();
}

struct Derv: public MyObj {};

int main()
{
  
  {
    MyObjPtr ptr1 = 0;
    MyObjPtr ptr2 = ptr1;
  }
  printf("objcount = %d\n", objcount);
  
  {
    MyObjPtr ptr1 = new MyObj();
    MyObjPtr ptr2 = ptr1;
    printf("objcount = %d (must be 1)\n", objcount);
    ptr1 = ptr2;
  }
  printf("objcount = %d\n", objcount);
  
  {
    MyObjPtr ptr1 = createMyObj();
    printf("objcount = %d (must be 1)\n", objcount);
    MyObjPtr ptr2;
    ptr2 = ptr1;
    ptr2 = 0;
    ptr1 = ptr2;
    printf("objcount = %d (must be 0)\n", objcount);
  }
  printf("objcount = %d\n", objcount);

  {
    vector<MyObjPtr> v;
    MyObjPtr p1 = new MyObj();
    MyObjPtr p2 = createMyObj();
    MyObjPtr p3 = p1;
    MyObjPtr p4;
    p4 = p2;
    printf("objcount = %d (must be 2)\n", objcount);

    v.push_back(new MyObj());
    v.push_back(new MyObj());
    v.push_back(p1);
    v.push_back(p1);
    v.push_back(p2);
    v.push_back(p2);
    v.push_back(p3);
    v.push_back(p3);
    v.push_back(p4);
    v.push_back(p4);
    printf("objcount = %d (must be 4)\n", objcount);
    
    p2 = 0;
    v.push_back(p4);  // p2がリリースされてもp4が生きている事を確認
    v.push_back(p4);
    printf("objcount = %d (must be 4)\n", objcount);
    
    p1 = p3 = 0;   // p1, p3 がなくなっても，vectorの中にいる
    printf("objcount = %d (must be 4)\n", objcount);

    p4 = new MyObj();
    v.push_back(p4);
    v.push_back(p4);
    printf("objcount = %d (must be 5)\n", objcount);
  }
  printf("objcount = %d\n", objcount);


  {
    Ptr<Derv> ptr1 = new Derv();
    MyObjPtr ptr2 = new Derv();
    printf("objcount = %d (must be 2)\n", objcount);
    
    ptr2 = ptr1;
    printf("objcount = %d (must be 1)\n", objcount);
  }
  printf("objcount = %d\n", objcount);
}



