1 // Slot.hh for FbTk, Fluxbox Toolkit 2 // Copyright (c) 2008 Henrik Kinnunen (fluxgen at fluxbox dot org) 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a 5 // copy of this software and associated documentation files (the "Software"), 6 // to deal in the Software without restriction, including without limitation 7 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 // and/or sell copies of the Software, and to permit persons to whom the 9 // Software is furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 // DEALINGS IN THE SOFTWARE. 21 22 #ifndef FBTK_SLOT_HH 23 #define FBTK_SLOT_HH 24 25 #include "NotCopyable.hh" 26 27 namespace FbTk { 28 29 /// \namespace Implementation details for signals, do not use anything in this namespace 30 namespace SigImpl { 31 32 struct EmptyArg {}; 33 34 /** A base class for all slots. It's purpose is to provide a virtual destructor and to enable the 35 * Signal class to hold a pointer to a generic slot. 36 */ 37 class SlotBase: private FbTk::NotCopyable { 38 public: ~SlotBase()39 virtual ~SlotBase() {} 40 }; 41 42 } // namespace SigImpl 43 44 /** Declares a pure virtual function call operator with a specific number of arguments (depending 45 * on the template specialization). This allows us to "call" any functor in an opaque way. 46 */ 47 template<typename ReturnType, typename Arg1 = SigImpl::EmptyArg, 48 typename Arg2 = SigImpl::EmptyArg, typename Arg3 = SigImpl::EmptyArg> 49 class Slot: public SigImpl::SlotBase { 50 public: 51 virtual ReturnType operator()(Arg1, Arg2, Arg3) = 0; 52 }; 53 54 /// Specialization for two arguments 55 template<typename ReturnType, typename Arg1, typename Arg2> 56 class Slot<ReturnType, Arg1, Arg2, SigImpl::EmptyArg>: public SigImpl::SlotBase { 57 public: 58 virtual ReturnType operator()(Arg1, Arg2) = 0; 59 }; 60 61 /// Specialization for one argument 62 template<typename ReturnType, typename Arg1> 63 class Slot<ReturnType, Arg1, SigImpl::EmptyArg, SigImpl::EmptyArg>: public SigImpl::SlotBase { 64 public: 65 virtual ReturnType operator()(Arg1) = 0; 66 }; 67 68 /// Specialization for no arguments 69 template<typename ReturnType> 70 class Slot<ReturnType, SigImpl::EmptyArg, SigImpl::EmptyArg, SigImpl::EmptyArg>: public SigImpl::SlotBase { 71 public: 72 virtual ReturnType operator()() = 0; 73 }; 74 75 /** A class which knows how to call a specific functor. It inherits from Slot and implemetents 76 * the function call operator 77 */ 78 template<typename Functor, typename ReturnType, typename Arg1 = SigImpl::EmptyArg, 79 typename Arg2 = SigImpl::EmptyArg, typename Arg3 = SigImpl::EmptyArg> 80 class SlotImpl: public Slot<ReturnType, Arg1, Arg2, Arg3> { 81 public: operator ()(Arg1 arg1,Arg2 arg2,Arg3 arg3)82 virtual ReturnType operator()(Arg1 arg1, Arg2 arg2, Arg3 arg3) 83 { return static_cast<ReturnType>(m_functor(arg1, arg2, arg3)); } 84 SlotImpl(Functor functor)85 SlotImpl(Functor functor) : m_functor(functor) {} 86 87 private: 88 Functor m_functor; 89 }; 90 91 /// Specialization for two arguments 92 template<typename Functor, typename ReturnType, typename Arg1, typename Arg2> 93 class SlotImpl<Functor, ReturnType, Arg1, Arg2, SigImpl::EmptyArg>: public Slot<ReturnType, Arg1, Arg2> { 94 public: operator ()(Arg1 arg1,Arg2 arg2)95 virtual ReturnType operator()(Arg1 arg1, Arg2 arg2) 96 { return static_cast<ReturnType>(m_functor(arg1, arg2)); } 97 SlotImpl(Functor functor)98 SlotImpl(Functor functor) : m_functor(functor) {} 99 100 private: 101 Functor m_functor; 102 }; 103 104 /// Specialization for one argument 105 template<typename Functor, typename ReturnType, typename Arg1> 106 class SlotImpl<Functor, ReturnType, Arg1, SigImpl::EmptyArg, SigImpl::EmptyArg>: public Slot<ReturnType, Arg1> { 107 public: operator ()(Arg1 arg1)108 virtual ReturnType operator()(Arg1 arg1) { return static_cast<ReturnType>(m_functor(arg1)); } 109 SlotImpl(Functor functor)110 SlotImpl(Functor functor) : m_functor(functor) {} 111 112 private: 113 Functor m_functor; 114 }; 115 116 /// Specialization for no arguments 117 template<typename Functor, typename ReturnType> 118 class SlotImpl<Functor, ReturnType, SigImpl::EmptyArg, SigImpl::EmptyArg, SigImpl::EmptyArg>: public Slot<ReturnType> { 119 public: operator ()()120 virtual ReturnType operator()() { return static_cast<ReturnType>(m_functor()); } 121 SlotImpl(Functor functor)122 SlotImpl(Functor functor) : m_functor(functor) {} 123 124 private: 125 Functor m_functor; 126 }; 127 128 } // namespace FbTk 129 130 #endif // FBTK_SLOT_H 131