// Vaca - Visual Application Components Abstraction // Copyright (c) 2005-2009 David Capello // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in // the documentation and/or other materials provided with the // distribution. // * Neither the name of the author nor the names of its contributors // may be used to endorse or promote products derived from this // software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED // OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef VACA_BIND_H #define VACA_BIND_H namespace Vaca { /** @defgroup bind_group Bind Classes and Functions @{ */ // ====================================================================== // BindAdapter0_fun /** @see @ref page_bind */ template class BindAdapter0_fun { F f; public: BindAdapter0_fun(const F& f) : f(f) { } R operator()() { return f(); } template R operator()(const A1& a1) { return f(); } template R operator()(const A1& a1, const A2& a2) { return f(); } template R operator()(const A1& a1, const A2& a2, const A3& a3) { return f(); } template R operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { return f(); } }; /** @see @ref page_bind */ template class BindAdapter0_fun { F f; public: BindAdapter0_fun(const F& f) : f(f) { } void operator()() { f(); } template void operator()(const A1& a1) { f(); } template void operator()(const A1& a1, const A2& a2) { f(); } template void operator()(const A1& a1, const A2& a2, const A3& a3) { f(); } template void operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { f(); } }; /** @see @ref page_bind */ template BindAdapter0_fun Bind(const F& f) { return BindAdapter0_fun(f); } // ====================================================================== // BindAdapter0_mem /** @see @ref page_bind */ template class BindAdapter0_mem { R (T::*m)(); T* t; public: template BindAdapter0_mem(R (T::*m)(), T2* t) : m(m), t(t) { } R operator()() { return (t->*m)(); } template R operator()(const A1& a1) { return (t->*m)(); } template R operator()(const A1& a1, const A2& a2) { return (t->*m)(); } template R operator()(const A1& a1, const A2& a2, const A3& a3) { return (t->*m)(); } template R operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { return (t->*m)(); } }; /** @see @ref page_bind */ template class BindAdapter0_mem { void (T::*m)(); T* t; public: template BindAdapter0_mem(void (T::*m)(), T2* t) : m(m), t(t) { } void operator()() { (t->*m)(); } template void operator()(const A1& a1) { (t->*m)(); } template void operator()(const A1& a1, const A2& a2) { (t->*m)(); } template void operator()(const A1& a1, const A2& a2, const A3& a3) { (t->*m)(); } template void operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { (t->*m)(); } }; /** @see @ref page_bind */ template BindAdapter0_mem Bind(R (T::*m)(), T2* t) { return BindAdapter0_mem(m, t); } // ====================================================================== // BindAdapter1_fun /** @see @ref page_bind */ template class BindAdapter1_fun { F f; X1 x1; public: BindAdapter1_fun(const F& f, X1 x1) : f(f), x1(x1) { } R operator()() { return f(x1); } template R operator()(const A1& a1) { return f(x1); } template R operator()(const A1& a1, const A2& a2) { return f(x1); } template R operator()(const A1& a1, const A2& a2, const A3& a3) { return f(x1); } template R operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { return f(x1); } }; /** @see @ref page_bind */ template class BindAdapter1_fun { F f; X1 x1; public: BindAdapter1_fun(const F& f, X1 x1) : f(f), x1(x1) { } void operator()() { f(x1); } template void operator()(A1& a1) { f(x1); } template void operator()(A1& a1, A2& a2) { f(x1); } template void operator()(A1& a1, A2& a2, A3& a3) { f(x1); } template void operator()(A1& a1, A2& a2, A3& a3, A4& a4) { f(x1); } }; /** @see @ref page_bind */ template BindAdapter1_fun Bind(const F& f, X1 x1) { return BindAdapter1_fun(f, x1); } // ====================================================================== // BindAdapter1_mem /** @see @ref page_bind */ template class BindAdapter1_mem { R (T::*m)(B1); T* t; X1 x1; public: template BindAdapter1_mem(R (T::*m)(B1), T2* t, X1 x1) : m(m), t(t), x1(x1) { } R operator()() { return (t->*m)(x1); } template R operator()(const A1& a1) { return (t->*m)(x1); } template R operator()(const A1& a1, const A2& a2) { return (t->*m)(x1); } template R operator()(const A1& a1, const A2& a2, const A3& a3) { return (t->*m)(x1); } template R operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { return (t->*m)(x1); } }; /** @see @ref page_bind */ template class BindAdapter1_mem { void (T::*m)(B1); T* t; X1 x1; public: template BindAdapter1_mem(void (T::*m)(B1), T2* t, X1 x1) : m(m), t(t), x1(x1) { } void operator()() { (t->*m)(x1); } template void operator()(const A1& a1) { (t->*m)(x1); } template void operator()(const A1& a1, const A2& a2) { (t->*m)(x1); } template void operator()(const A1& a1, const A2& a2, const A3& a3) { (t->*m)(x1); } template void operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { (t->*m)(x1); } }; /** @see @ref page_bind */ template BindAdapter1_mem Bind(R (T::*m)(B1), T2* t, X1 x1) { return BindAdapter1_mem(m, t, x1); } // ====================================================================== // BindAdapter2_fun /** @see @ref page_bind */ template class BindAdapter2_fun { F f; X1 x1; X2 x2; public: BindAdapter2_fun(const F& f, X1 x1, X2 x2) : f(f), x1(x1), x2(x2) { } R operator()() { return f(x1, x2); } template R operator()(const A1& a1) { return f(x1, x2); } template R operator()(const A1& a1, const A2& a2) { return f(x1, x2); } template R operator()(const A1& a1, const A2& a2, const A3& a3) { return f(x1, x2); } template R operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { return f(x1, x2); } }; /** @see @ref page_bind */ template class BindAdapter2_fun { F f; X1 x1; X2 x2; public: BindAdapter2_fun(const F& f, X1 x1, X2 x2) : f(f), x1(x1), x2(x2) { } void operator()() { f(x1, x2); } template void operator()(const A1& a1) { f(x1, x2); } template void operator()(const A1& a1, const A2& a2) { f(x1, x2); } template void operator()(const A1& a1, const A2& a2, const A3& a3) { f(x1, x2); } template void operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { f(x1, x2); } }; /** @see @ref page_bind */ template BindAdapter2_fun Bind(const F& f, X1 x1, X2 x2) { return BindAdapter2_fun(f, x1, x2); } // ====================================================================== // BindAdapter2_mem /** @see @ref page_bind */ template class BindAdapter2_mem { R (T::*m)(B1, B2); T* t; X1 x1; X2 x2; public: template BindAdapter2_mem(R (T::*m)(B1, B2), T2* t, X1 x1, X2 x2) : m(m), t(t), x1(x1), x2(x2) { } R operator()() { return (t->*m)(x1, x2); } template R operator()(const A1& a1) { return (t->*m)(x1, x2); } template R operator()(const A1& a1, const A2& a2) { return (t->*m)(x1, x2); } template R operator()(const A1& a1, const A2& a2, const A3& a3) { return (t->*m)(x1, x2); } template R operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { return (t->*m)(x1, x2); } }; /** @see @ref page_bind */ template class BindAdapter2_mem { void (T::*m)(B1, B2); T* t; X1 x1; X2 x2; public: template BindAdapter2_mem(void (T::*m)(B1, B2), T2* t, X1 x1, X2 x2) : m(m), t(t), x1(x1), x2(x2) { } void operator()() { (t->*m)(x1, x2); } template void operator()(const A1& a1) { (t->*m)(x1, x2); } template void operator()(const A1& a1, const A2& a2) { (t->*m)(x1, x2); } template void operator()(const A1& a1, const A2& a2, const A3& a3) { (t->*m)(x1, x2); } template void operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { (t->*m)(x1, x2); } }; /** @see @ref page_bind */ template BindAdapter2_mem Bind(R (T::*m)(B1, B2), T2* t, X1 x1, X2 x2) { return BindAdapter2_mem(m, t, x1, x2); } // ====================================================================== // BindAdapter3_fun /** @see @ref page_bind */ template class BindAdapter3_fun { F f; X1 x1; X2 x2; X3 x3; public: BindAdapter3_fun(const F& f, X1 x1, X2 x2, X3 x3) : f(f), x1(x1), x2(x2), x3(x3) { } R operator()() { return f(x1, x2, x3); } template R operator()(const A1& a1) { return f(x1, x2, x3); } template R operator()(const A1& a1, const A2& a2) { return f(x1, x2, x3); } template R operator()(const A1& a1, const A2& a2, const A3& a3) { return f(x1, x2, x3); } template R operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { return f(x1, x2, x3); } }; /** @see @ref page_bind */ template class BindAdapter3_fun { F f; X1 x1; X2 x2; X3 x3; public: BindAdapter3_fun(const F& f, X1 x1, X2 x2, X3 x3) : f(f), x1(x1), x2(x2), x3(x3) { } void operator()() { f(x1, x2, x3); } template void operator()(const A1& a1) { f(x1, x2, x3); } template void operator()(const A1& a1, const A2& a2) { f(x1, x2, x3); } template void operator()(const A1& a1, const A2& a2, const A3& a3) { f(x1, x2, x3); } template void operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { f(x1, x2, x3); } }; /** @see @ref page_bind */ template BindAdapter3_fun Bind(const F& f, X1 x1, X2 x2, X3 x3) { return BindAdapter3_fun(f, x1, x2, x3); } // ====================================================================== // BindAdapter3_mem /** @see @ref page_bind */ template class BindAdapter3_mem { R (T::*m)(B1, B2, B3); T* t; X1 x1; X2 x2; X3 x3; public: template BindAdapter3_mem(R (T::*m)(B1, B2, B3), T2* t, X1 x1, X2 x2, X3 x3) : m(m), t(t), x1(x1), x2(x2), x3(x3) { } R operator()() { return (t->*m)(x1, x2, x3); } template R operator()(const A1& a1) { return (t->*m)(x1, x2, x3); } template R operator()(const A1& a1, const A2& a2) { return (t->*m)(x1, x2, x3); } template R operator()(const A1& a1, const A2& a2, const A3& a3) { return (t->*m)(x1, x2, x3); } template R operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { return (t->*m)(x1, x2, x3); } }; /** @see @ref page_bind */ template class BindAdapter3_mem { void (T::*m)(B1, B2, B3); T* t; X1 x1; X2 x2; X3 x3; public: template BindAdapter3_mem(void (T::*m)(B1, B2, B3), T2* t, X1 x1, X2 x2) : m(m), t(t), x1(x1), x2(x2) { } void operator()() { (t->*m)(x1, x2, x3); } template void operator()(const A1& a1) { (t->*m)(x1, x2, x3); } template void operator()(const A1& a1, const A2& a2) { (t->*m)(x1, x2, x3); } template void operator()(const A1& a1, const A2& a2, const A3& a3) { (t->*m)(x1, x2, x3); } template void operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { (t->*m)(x1, x2, x3); } }; /** @see @ref page_bind */ template BindAdapter3_mem Bind(R (T::*m)(B1, B2, B3), T2* t, X1 x1, X2 x2) { return BindAdapter3_mem(m, t, x1, x2); } // ====================================================================== // RefWrapper /** @todo @see @ref page_bind */ template class RefWrapper { T* ptr; public: RefWrapper(T& ref) : ptr(&ref) { } operator T&() const { return *ptr; } }; /** Creates RefWrappers, useful to wrap arguments that have to be passed as a reference when you use Bind. @see @ref page_bind */ template RefWrapper Ref(T& ref) { return RefWrapper(ref); } /** @} */ } // namespace Vaca #endif // VACA_BIND_H