#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <list>

template<typename T>
class CCgiDataCapsule {
 private:
  T* m_value;
 public:
  T* value() {
    if (m_value == NULL) {
      printf("Alloc Memory!!(%d)\n", sizeof(T));
      m_value = (T*)malloc(sizeof(T));
    }
    return m_value;
  }

  bool IsSet() const {
    return m_value != NULL;
  }

  void Release() {
    if (m_value != NULL) {
      printf("Free Memory!!\n");
      free(m_value);
      m_value = NULL;
    }
  }

  CCgiDataCapsule() : m_value(NULL) {
  }

  ~CCgiDataCapsule() {
    Release();
  }
};

template<typename T>
class CCgiDataCapsuleStatic {
 private:
  T m_value;
  bool m_isSet;
 public:
  T& value() {
    returm m_value;
  }

  bool& isSet() {
    return m_isSet;
  }

  CCgiDataCapsuleStatic() : m_isSet(false) {
  }
};


class CCgiDataItem {
 protected:
  const char* m_subject;
  const char* m_item;

 public:
  virtual bool Get() = 0;
  virtual bool Set() = 0;

  CCgiDataItem(const char* subject, const char* item)
    : m_subject(subject), m_item(item) { }
  virtual ~CCgiDataItem() { }
};

class CCgiDateItemU8 : public CCgiDataItem {
 private:
  unsigned char m_data;

 public:
   CCgiDateItemU8(const char* subject, const char* item) : CCgiDataItem(subject, item) { }
   ~CCgiDateItemU8() { }

   bool Get() {
     m_data = 3;
     return true;
   }
   bool Set() {
   }
};

class CCgiDataRestoreManager {
 private:
   std::list<CCgiDataItem*> m_list;

  public:
   void AddItem(CCgiDataItem* item) {
     m_list.push_back(item);
   }

   void RestoreAll() {
     for (auto it = m_list.begin(); it != m_list.end(); ++it) {
       (*it)->Set();
     }
   }

   ~CCgiDataRestoreManager() {
     for (auto it = m_list.begin(); it != m_list.end(); ++it) {
       delete (*it);
     }
   }
  
};

void GetValue(int* data) {
  *data = 3;
}

int main() {
  CCgiDataCapsule<char[64]> stringData;
  CCgiDataCapsule<char[32]> stringData2;
  CCgiDataCapsule<int> intData;

  strcpy(*stringData.value(), "Hello, World!\n");

  if (stringData.IsSet()) {
    printf("%s\n", *stringData.value());
  }
  if (stringData2.IsSet()) {
    printf("%s\n", *stringData2.value());
  }

  GetValue(intData.value());

  printf("data=%d\n", intData.value());

  return 0;
}
