#include <iostream>

using namespace std;

#include "smartPointer.hpp"
#include "autoPointer.hpp"
#include "deepPointer.hpp"
#include "smartArray.hpp"
#include "autoArray.hpp"
#include "policy.hpp"

#include "autoStr.hpp"

/*todo
smart -> auto convertion

string manipulation
*/


template <typename what, typename T, T val>
what smartReturner()
{
    what tmp(new T);
    *tmp = val;
    return tmp;
}

template <typename what>
void smartExplicit(what cal)
{
    cout << "by value " << *cal << endl;
}

template <typename what, typename T, T val>
void test()
{
    what testPtr(new T);
    *testPtr = val;
    what test2Ptr = testPtr,
         test3Ptr(testPtr),
         test5Ptr = smartReturner<what,T,val>();
    if(testPtr)
    cout << "creation " << *testPtr << endl;
    if(test2Ptr)
    cout << "assignation " << *test2Ptr << endl;
    if(test3Ptr)
    cout << "copy " << *test3Ptr << endl;
    if(testPtr)
    smartExplicit<what>(testPtr);
    cout << "return by value direct" << *smartReturner<what,T,val>() << endl;
    if(test5Ptr)
    cout << "return by value assigned to declaration " << *test5Ptr << endl;
    smartExplicit<what>(smartReturner<what,T,val>());
}

template<typename T>
void autotmp(T a)
{
    cout << a << endl;
}



int main()
{
//    test<smartPtr<char>,char,'!'>();

//    autotmp(5);
    
    autoArray<char> t(new char[20]);
    smartArray<char> tt(new char[10]);

    autoPtr<int> a(new int);
    smartPtr<int> b(new int);
    deepPtr<int> c(new int);

    autoStr<> h("helloword!\n");
    
    cout << *h;

    return 0;
}
