#include <memory>
#include <typeindex>
#include <iostream>
#include <string>
#include <vector>
#include <map>
typedef std::multimap<std::type_index, void*> Object;
typedef std::map<Object, std::shared_ptr<void>> ObjectCollection;
Object object;
ObjectCollection objectCollection;
template<typename T, typename... Args>
T* getResource(Args&& ... args)
{
// Creating tuple from the arguments
std::tuple<Args...> currentArgs(std::forward<Args>(args)...);
// Getting object type info
std::type_index type = { typeid(T) };
// Getting all objects from the collection that are of the same type
auto range = object.equal_range(type);
for (auto it = range.first; it != range.second; ++it)
{
// it->second is a void* Since we are iterating through
// the the collection of the same type I'm trying to cast
// back. Object construct parameters should be the same
// (in this example: const std::string &fileName)
auto storedArgs = *static_cast<std::tuple<Args...>*>(it->second);
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Problem is here. currentArgs and storedArgs are always equal :/
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Return the object from the collection if current arguments and
// arguments from the collection are the same
if (currentArgs == storedArgs)
{
std::cout << "Found... returning..." << std::endl;
// found... return...
return static_cast<T*>(objectCollection[object].get());
}
}
// Object with the same arguments were not found
// Adding to collection and return
std::cout << "Adding to collection..." << std::endl;
object.emplace(type, ¤tArgs);
objectCollection[object] = std::make_shared<T>(std::forward<Args>(args)...);
return static_cast<T*>(objectCollection[object].get());
}
class Resource
{
public:
virtual ~Resource() = default;
template<typename T, typename... Args>
static T* get(Args&& ... args)
{
return getResource<T>(std::forward<Args>(args)...);
}
};
class Image
{
public:
Image(const std::string &fileName)
{
std::cout << "Loading image " << fileName.c_str() << std::endl;
}
~Image(){};
};
int main()
{
auto image1 = Resource::get<Image>("aaa.jpg");
auto image2 = Resource::get<Image>("bbb.jpg");
auto image3 = Resource::get<Image>("aaa.jpg");
//getchar();
}