#pragma once

#include <string>
#include <random>
#include <memory>
#include <vector>


class Object {
 public:
    virtual std::string ToString() const = 0;

    virtual ~Object() {}
};

class NewSmth : public Object {
 public:
    explicit NewSmth(const std::string &class_id) {
        class_id_ = class_id;
    }

    std::string ToString() const override {
        return class_id_;
    }

 private:
    std::string class_id_;
};

Object *NewSomeObject(const std::string &class_id) {
    return new NewSmth(class_id);
}

class Factory {
 public:
    void Register(const std::string &class_id, Object *(*instance_creator)()) {
        this->ids.push_back(class_id);
        this->funcs.push_back(instance_creator);
    }

    Object *Create(const std::string &basicString) {
        for (const auto &i : this->std_ids) {
            if (i == basicString) {
                return NewSomeObject(basicString);
            }
        }
        for (int i = 0; i < this->ids.size(); i++) {
            if (this->ids[i] == basicString) {
                return this->funcs[i]();
            }
        }
    }

 private:
    std::vector<std::string> std_ids{"list",
    "apple!",
    "yet another identifier"};
    std::vector<std::string> ids;
    std::vector<Object *(*)()> funcs;
};