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