fork download
  1. #include <memory>
  2. #include <typeindex>
  3. #include <iostream>
  4. #include <string>
  5. #include <vector>
  6. #include <map>
  7.  
  8. typedef std::multimap<std::type_index, void*> Object;
  9. typedef std::map<Object, std::shared_ptr<void>> ObjectCollection;
  10.  
  11. Object object;
  12. ObjectCollection objectCollection;
  13.  
  14. template<typename T, typename... Args>
  15. T* getResource(Args&& ... args)
  16. {
  17. // Creating tuple from the arguments
  18. std::tuple<Args...> currentArgs(std::forward<Args>(args)...);
  19. // Getting object type info
  20. std::type_index type = { typeid(T) };
  21.  
  22. // Getting all objects from the collection that are of the same type
  23. auto range = object.equal_range(type);
  24.  
  25. for (auto it = range.first; it != range.second; ++it)
  26. {
  27. // it->second is a void* Since we are iterating through
  28. // the the collection of the same type I'm trying to cast
  29. // back. Object construct parameters should be the same
  30. // (in this example: const std::string &fileName)
  31. auto storedArgs = *static_cast<std::tuple<Args...>*>(it->second);
  32.  
  33. // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  34. // Problem is here. currentArgs and storedArgs are always equal :/
  35. // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  36. // Return the object from the collection if current arguments and
  37. // arguments from the collection are the same
  38. if (currentArgs == storedArgs)
  39. {
  40. std::cout << "Found... returning..." << std::endl;
  41. // found... return...
  42. return static_cast<T*>(objectCollection[object].get());
  43. }
  44. }
  45.  
  46. // Object with the same arguments were not found
  47. // Adding to collection and return
  48. std::cout << "Adding to collection..." << std::endl;
  49. object.emplace(type, &currentArgs);
  50. objectCollection[object] = std::make_shared<T>(std::forward<Args>(args)...);
  51. return static_cast<T*>(objectCollection[object].get());
  52. }
  53.  
  54. class Resource
  55. {
  56. public:
  57. virtual ~Resource() = default;
  58.  
  59. template<typename T, typename... Args>
  60. static T* get(Args&& ... args)
  61. {
  62. return getResource<T>(std::forward<Args>(args)...);
  63. }
  64. };
  65.  
  66. class Image
  67. {
  68. public:
  69. Image(const std::string &fileName)
  70. {
  71. std::cout << "Loading image " << fileName.c_str() << std::endl;
  72. }
  73.  
  74. ~Image(){};
  75. };
  76.  
  77. int main()
  78. {
  79. auto image1 = Resource::get<Image>("aaa.jpg");
  80. auto image2 = Resource::get<Image>("bbb.jpg");
  81. auto image3 = Resource::get<Image>("aaa.jpg");
  82. //getchar();
  83. }
Success #stdin #stdout 0s 3472KB
stdin
Standard input is empty
stdout
Adding to collection...
Loading image aaa.jpg
Found... returning...
Found... returning...