Thursday, May 10, 2018

How to print ClassName


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#ifndef __CNAME_H__
#define __CNAME_H__

#include <string>


inline std::string className(const std::string& prettyFunction)
{
    size_t colons = prettyFunction.find("::");
    if (colons == std::string::npos)
        return "::";

    size_t begin = prettyFunction.find_last_of("::") + 1;
    return prettyFunction.substr(begin);
}

#ifdef __GNUC__
#define __CLASS_NAME__ className(__PRETTY_FUNCTION__)
#define __FUNCNAME__ __PRETTY_FUNCTION__
#else
#define __CLASS_NAME__ className(__FUNCTION__)
#define __FUNCNAME__ __FUNCTION__
#endif

#endif

Vector of Smart Pointers with Template


#include <iostream>
#include <vector>
#include <memory>
#include <sstream>
#include <string>
#include <typeinfo>


// Require C++ version 14 to compile!

class Base
{
public:
    Base(Base & other);
    Base(Base *);
    Base(char const * const tag, char const * const desc) : m_tag(tag), m_desc(desc) {}
    //Base(std::string const & tag, std::string const & desc) : m_tag(tag), m_desc(desc) {}
    ~Base() = default;

    void print();
    virtual void Process(); 

public:
    std::string m_tag = "";
    std::string m_desc = "";
};



Base::Base(Base & rhs)
{
    m_tag = rhs.m_tag;
    m_desc = rhs.m_desc;
}


Base::Base(Base *pOther)
{
    m_tag = pOther->m_tag;
    m_desc = pOther->m_desc;
}


void Base::print()
{
    std::cout << __FUNCTION__ << "(" << this << "): Base::m_tag = " << m_tag << std::endl 
              << "                  Base::m_desc = " << m_desc << std::endl;
}


void Base::Process()
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}



template <class CNAME>
Base* createClass(char const *const tag, char const * const desc)
{
    CNAME * pObj  = new CNAME(tag,desc);

    std::cout << "Inside " << __FUNCTION__  << "(): ";
    pObj->Process();
    return dynamic_cast<Base*>(pObj);
}


template <class CNAME>
std::unique_ptr<Base> createUniqueClass(char const *const tag, char const *const desc)
{
    std::unique_ptr<Base> obj(createClass<CNAME>(tag, desc));
    return obj;
}



class KelasA : public Base
{
public:
    KelasA(char const * const tag, char const * const desc) : Base(tag, desc) {}
 static std::string const DefaultKelasName;

    void Process() override;
private:
 std::string m_name = DefaultKelasName;
};

std::string const KelasA::DefaultKelasName = "A";




void KelasA::Process()
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}


class KelasB : public Base
{
public:
    KelasB(char const * const tag, char const * const desc) : Base(tag, desc) {}
 static std::string const DefaultKelasName;
    void Process() override;
private:
 std::string m_name = DefaultKelasName;
};


std::string const KelasB::DefaultKelasName = "B";


void KelasB::Process()
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}


class Container
{
public:
 template <class CNAME>
 void Add(std::string tag = "")
 {
  std::ostringstream sout;
  sout << __FUNCTION__ << ":Entry=" << m_bin.size();
  #define ANAM(x) #x
  m_bin.push_back(createUniqueClass<CNAME>(tag.c_str(), const_cast<char const *>(sout.str().c_str())));
 }

 void Process();


private:
    std::vector<std::unique_ptr<Base>> m_bin;
};



void Container::Process()
{
 for(auto & v : m_bin)
    {
        v->Process();
        v->print();
    }
}


int main()
{
 Container c;

 for(auto i = 0; i<10; ++i)
 {
  c.Add<KelasA>("A");
  c.Add<KelasB>("B");
 }

 c.Process();
 
    return 0;
}

Vector of Smart Pointers (revised)

The previous example doesn't really show the polymorphism. This example shows the coolness of C++ (version 14):





#include <iostream>
#include <vector>
#include <memory>


// Require C++ version 14 to compile!

class Base
{
public:
    Base(Base & other);
    Base(Base *);
    Base(char const * const tag, char const * const desc) : m_tag(tag), m_desc(desc) {}
    ~Base() = default;

    void print();
    virtual void Process(); 

public:
    std::string m_tag = "";
    std::string m_desc = "";
};



Base::Base(Base & rhs)
{
    m_tag = rhs.m_tag;
    m_desc = rhs.m_desc;
}


Base::Base(Base *pOther)
{
    m_tag = pOther->m_tag;
    m_desc = pOther->m_desc;
}


void Base::print()
{
    std::cout << __FUNCTION__ << "(" << this << "): Base::m_tag = " << m_tag << std::endl 
              << "                  Base::m_desc = " << m_desc << std::endl;
}


void Base::Process()
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}



template <class CNAME>
Base* createClass(char const *const tag, char const * const desc)
{
    CNAME * pObj  = new CNAME(tag,desc);

    std::cout << "Inside " << __FUNCTION__  << "(): ";
    pObj->Process();
    return dynamic_cast<Base*>(pObj);
}


template <class CNAME>
std::unique_ptr<Base> createUniqueClass(char const *const tag, char const *const desc)
{
    std::unique_ptr<Base> obj(createClass<CNAME>(tag, desc));
    return obj;
}



class KelasA : public Base
{
public:

    KelasA(char const * const tag, char const * const desc) : Base(tag, desc) {}
    void Process() override;
};


void KelasA::Process()
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}


class KelasB : public Base
{
public:
    KelasB(char const * const tag, char const * const desc) : Base("B", desc) {}
    void Process() override;
};



void KelasB::Process()
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}




int main()
{
    std::vector<std::unique_ptr<Base>> vb;

    vb.push_back(createUniqueClass<KelasA>("A", "Kelase A-1"));

    vb.push_back(createUniqueClass<KelasB>("B", "Kelase B-1"));

    //for(auto v = vb.begin(); v != vb.end(); v++)a
    for(auto & v : vb)
    {
        v->Process();
        v->print();
    }

    return 0;
}

Wednesday, May 9, 2018

Vector of Smart Pointers

#include <iostream>
#include <vector>
#include <memory>


// Require C++ version 14 to compile!

class Base
{
public:
    Base(Base & other);
    Base(Base *);
    Base(char const * const tag, char const * const desc) : m_tag(tag), m_desc(desc) {}

    void print();

public:
    std::string m_tag = "";
    std::string m_desc = "";
};



Base::Base(Base & rhs)
{
    m_tag = rhs.m_tag;
    m_desc = rhs.m_desc;
}


Base::Base(Base *pOther)
{
    m_tag = pOther->m_tag;
    m_desc = pOther->m_desc;
}


void Base::print()
{
    std::cout << __FUNCTION__ << "(" << this << "): Base::m_tag = " << m_tag << std::endl 
              << "                  Base::m_desc = " << m_desc << std::endl;
}


template <class CNAME>
Base * createClass(char const *const tag, char const * const desc)
{
    CNAME *pObj = new CNAME(tag,desc);

    Base *pBase = dynamic_cast<Base*>(pObj);

    return pBase;
}




class KelasA : public Base
{
public:

    KelasA(char const * const tag, char const * const desc) : Base(tag, desc) {}
    void FuncA() {}
};

class KelasB : public Base
{
public:
    KelasB(char const * const tag, char const * const desc) : Base("B", desc) {}
    void FuncA() {}
};


int main()
{
    std::vector<std::unique_ptr<Base>> vb;

    std::unique_ptr<Base> p;
    p = std::make_unique<Base>((createClass<KelasA>("A", "Kelas A-1")));
    vb.push_back(std::move(p));
    p = std::make_unique<Base>((createClass<KelasB>("B", "Kelas B-1")));
    vb.push_back(std::move(p));

    for(auto v = vb.begin(); v != vb.end(); v++)
    {
        (*v)->print();
    }

    return 0;
}

Sunday, April 8, 2018

Stream of Prime Numbers

Create an endless stream of prime numbers - a bit like IntStream.of(2,3,5,7,11,13,17), but infinite. The stream must be able to produce a million primes in a few seconds.