fork download
  1. #include <iostream>
  2. #include <memory>
  3. #include <typeindex>
  4. #include <vector>
  5. #include <utility>
  6.  
  7. using namespace std;
  8.  
  9. // Predefine template delegate factory
  10. template < typename R, typename... Args >
  11. class brGenericDelegate ;
  12.  
  13. // C++11 template alias to announce functor definition
  14. template < typename R, typename... Args >
  15. using brGenericDelegateType = std::function< std::shared_ptr<R>(Args...) > ;
  16.  
  17. class brDelegate
  18. {
  19. protected:
  20. brDelegate(){}
  21.  
  22. public:
  23. virtual ~brDelegate() = default ;
  24.  
  25. template < typename R, typename... Args >
  26. static std::shared_ptr<brDelegate> create( typename brGenericDelegate<R,Args...>::functor func )
  27. {
  28. return std::make_shared<brGenericDelegate<R,Args...>>(func) ;
  29. }
  30.  
  31. template < typename R, typename... Args >
  32. std::shared_ptr<R> run( Args... args ) const
  33. {
  34. using derived_type = brGenericDelegate<R,Args...> ;
  35. return dynamic_cast< const derived_type& >(*this)(args...) ;
  36. }
  37.  
  38. template < typename R, typename... ARGS >
  39. bool isSignatureEquals(void) const
  40. {
  41. bool isEquals = false;
  42. if(this->getReturnType() == typeid(R)){
  43. if(this->getNumberOfArguments() == sizeof...(ARGS)){
  44. std::vector<std::type_index> args;
  45. args.insert(args.end(), {typeid(ARGS)...});
  46. if(args == this->getArgTypes()){
  47. isEquals = true;
  48. }
  49. }
  50. }
  51. return isEquals;
  52. }
  53.  
  54. protected:
  55. virtual std::type_index getReturnType(void) const = 0;
  56. virtual unsigned int getNumberOfArguments(void) const = 0;
  57. virtual const std::vector<std::type_index>& getArgTypes(void) const = 0;
  58. };
  59.  
  60. template < typename R, typename... Args >
  61. class brGenericDelegate : public brDelegate
  62. {
  63. public:
  64. using functor = brGenericDelegateType< R, Args... >;
  65. brGenericDelegate( functor f ) : fn(f) {
  66. m_args.insert(m_args.end(), {typeid(Args)...});
  67. }
  68.  
  69. std::shared_ptr<R> operator() ( Args... args ) const
  70. {
  71. return fn(args...) ;
  72. }
  73.  
  74. std::type_index getReturnType(void) const {
  75. return typeid(R);
  76. }
  77.  
  78. unsigned int getNumberOfArguments(void) const {
  79. return sizeof...(Args);
  80. }
  81.  
  82. const std::vector<std::type_index>& getArgTypes() const{
  83. return m_args;
  84. }
  85.  
  86. private:
  87. const functor fn ;
  88. std::vector<std::type_index> m_args;
  89. };
  90.  
  91. // Test interface 1
  92. class Gun
  93. {
  94. public:
  95. Gun(){}
  96. virtual ~Gun(){}
  97.  
  98. virtual std::string getName(void) const = 0;
  99. virtual std::string getType(void) const = 0;
  100. virtual double getCaliber(void) const = 0;
  101. };
  102.  
  103. class MachineGun : virtual public Gun
  104. {
  105. public:
  106. MachineGun(double caliber, const std::string name)
  107. :m_caliber(caliber), m_name(name){}
  108. virtual ~MachineGun(){}
  109.  
  110. virtual std::string getName(void) const {
  111. return m_name;
  112. }
  113.  
  114. virtual std::string getType(void) const {
  115. return "projectile";
  116. }
  117.  
  118. virtual double getCaliber(void) const {
  119. return m_caliber;
  120. }
  121.  
  122. private:
  123. double m_caliber;
  124. std::string m_name;
  125. };
  126.  
  127. class Armament
  128. {
  129. public:
  130. Armament(std::shared_ptr<Gun> primary)
  131. :m_primary(primary){}
  132. ~Armament(){}
  133.  
  134. const std::shared_ptr<Gun> getPrimaryWeapon(void){
  135. return m_primary;
  136. }
  137.  
  138. const std::shared_ptr<Gun> getSecondaryWeapon(void){
  139. return m_secondary;
  140. }
  141.  
  142. private:
  143. std::shared_ptr<Gun> m_primary = nullptr;
  144. std::shared_ptr<Gun> m_secondary = nullptr;
  145. };
  146.  
  147. class brImage;
  148. class brTexture
  149. {
  150. public:
  151. enum eTextureType{
  152. TYPE_TEXTURE_2D = 1,
  153. TYPE_TEXTURE_CUBEMAP = 2
  154. };
  155.  
  156. public:
  157. brTexture(eTextureType type){}
  158. virtual ~brTexture(){}
  159.  
  160. virtual void bind(unsigned int unit) = 0;
  161. virtual void unbind(unsigned int unit) = 0;
  162. virtual void update(void) = 0;
  163. };
  164.  
  165. class brGL3Texture : virtual public brTexture
  166. {
  167. public:
  168. brGL3Texture(brTexture::eTextureType type):brTexture(type){}
  169. virtual ~brGL3Texture(){}
  170.  
  171. void bind(unsigned int unit){}
  172. void unbind(unsigned int unit){}
  173. void update(void){}
  174.  
  175. protected:
  176. int m_textureID;
  177. };
  178.  
  179. class brGL3TextureSampler
  180. {
  181. public:
  182. brGL3TextureSampler(std::shared_ptr<brTexture> texture)
  183. :m_texture(texture){}
  184. virtual ~brGL3TextureSampler(){}
  185.  
  186. private:
  187. void init(void){}
  188. void bindTextureSampler(void){}
  189.  
  190. std::shared_ptr<brTexture> m_texture = nullptr;
  191. };
  192.  
  193. std::shared_ptr<brDelegate> delegate = nullptr;
  194.  
  195. // Perfect forwarding test function
  196. template <typename R, typename ... ARGS>
  197. std::shared_ptr<R> resolve(ARGS&& ... args)
  198. {
  199. return delegate->run<R, ARGS...>(std::forward<ARGS>(args)...);
  200. }
  201.  
  202. int main() {
  203.  
  204. auto gun_factory = brDelegate::create<MachineGun, double, std::string>
  205. ([] (double caliber, const std::string& name) -> std::shared_ptr<MachineGun>
  206. { return std::make_shared<MachineGun>(caliber, name); });
  207. auto gun = gun_factory->run<MachineGun, double, std::string>(50.0, "BAR");
  208.  
  209. delegate = brDelegate::create<Armament, std::shared_ptr<Gun>>
  210. ([] (std::shared_ptr<Gun> primary) -> std::shared_ptr<Armament> { return std::make_shared<Armament>(primary); });
  211.  
  212. auto test = resolve<Armament, std::shared_ptr<Gun>>(gun);
  213.  
  214.  
  215. auto tex_factory = brDelegate::create<brTexture, brTexture::eTextureType>
  216. ([] (brTexture::eTextureType type) -> std::shared_ptr<brTexture>
  217. { return std::make_shared<brGL3Texture>(type); });
  218.  
  219. auto texture = std::make_shared<brGL3Texture>(brTexture::TYPE_TEXTURE_2D);
  220. //auto texture = tex_factory->run<brTexture, brTexture::eTextureType>(brTexture::TYPE_TEXTURE_2D);
  221.  
  222. delegate = brDelegate::create<brGL3TextureSampler, std::shared_ptr<brTexture>>
  223. ([] (std::shared_ptr<brTexture> tex) -> std::shared_ptr<brGL3TextureSampler>
  224. { return std::make_shared<brGL3TextureSampler>(tex); });
  225.  
  226. auto test1 = resolve<brGL3TextureSampler, std::shared_ptr<brTexture>>(texture);
  227. return 0;
  228. }
Success #stdin #stdout 0s 3444KB
stdin
Standard input is empty
stdout
Standard output is empty