How to identify for polymorphic classes

## requirements
* C++11

## code

### inherits.hpp

```cpp
#pragma once
#include <type_traits>
#include <utility>

namespace util {
    template<class... T>
    struct inherit{
        template<class...Args>
        inherit(Args&&...){};
    };

    template<class T>
    struct inherit<T> : T{
        template<class...Args>
        inherit(Args&&...args) : T(std::forward<Args>(args)...){};
    };

    template<class H, class... T>
    struct inherit<H,T...> : H, inherit<T...> {
        template<class...Args>
        inherit(Args&&... args) : H(args...), inherit<T...>(std::forward<Args>(args)...){};
    };
}
```

### class_identity.hpp

```cpp
#pragma once
#include "util/inherit.hpp"
#include <cstdint>

namespace util {
    namespace class_identity_detail {
        using class_identifier_t = uint32_t;
        struct identity_factory {
            static class_identifier_t get_id() {
                static class_identifier_t value = 0;
                return value++;
            }
        };

        template<class T>
        struct identity_holder {
            using value_type = class_identifier_t;
            identity_holder() : value(identity_factory::get_id()) {};
            static class_identifier_t get_identity() {
                static const identity_holder temp;
                return temp.get_internal_identity();
            }
        private:
            class_identifier_t get_internal_identity() const {
                return this->value;
            }
            const class_identifier_t value;
        };
        template<class T, class...Bases>
        struct class_identity : public inherit<Bases...>{
            template<class...Args>
            class_identity(Args&&... args) : inherit<Bases...>(std::forward<Args>(args)...) {};
            using base_type = class_identity;
            using identity_type = identity_holder<T>;
            virtual typename identity_type::value_type get_identity() const {
                return identity_type::get_identity();
            }
            static typename identity_type::value_type get_identity_static() {
                return identity_type::get_identity();
            }
        };
    }
    namespace types {
        using class_identifier_t = class_identity_detail::class_identifier_t;
    }
    template<class T, class... Bases>
    using class_identity = class_identity_detail::class_identity<T, Bases...>;
}
```

## usage

### main.cpp
```cpp
#include "util/class_identity.hpp"
#include <iostream>
#include <memory>
#include <unordered_map>
#include <string>

struct base_t : public util::class_identity<base_t> {
    virtual void test() {
        std::cout << "base" << std::endl;
    }
};

struct deriv_t : public util::class_identity<deriv_t, base_t> {
    virtual void test() {
        std::cout << "deriv" << std::endl;
    }
};

int main() {
    std::shared_ptr<base_t> v = std::make_shared<deriv_t>();
    v->test(); // print -> deriv
    std::unordered_map<util::types::class_identifier_t,std::string> type_map = {
        {base_t::get_identity_static(), "base"},
        {deriv_t::get_identity_static(), "deriv"}
    };
    std::cout << "type is " << type_map[v->get_identity()] << std::endl; // print -> type is deriv
}
```

## What to use for?
maybe... so for meta-programming???
well then, use for debug?

## Wandbox
https://wandbox.org/permlink/nbuxQ4T9q6FaFKat