/* grive: an GPL program to sync a local directory with Google Drive Copyright (C) 2012 Wan Wai Ho This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include #include namespace gr { namespace impl { template class FuncImpl ; template class FuncImpl { public : virtual R operator()( ) = 0 ; virtual FuncImpl* Clone() const = 0 ; virtual ~FuncImpl() {} } ; template class FuncImpl { public : virtual R operator()(P1) = 0 ; virtual FuncImpl* Clone() const = 0 ; virtual ~FuncImpl() {} } ; template class FuncImpl { public : virtual R operator()(P1,P2) = 0 ; virtual FuncImpl* Clone() const = 0 ; virtual ~FuncImpl() {} } ; template struct FuncTrait ; struct NullType {} ; template struct FuncTrait { typedef R ReturnType ; typedef NullType Param1Type ; typedef NullType Param2Type ; } ; template struct FuncTrait { typedef R ReturnType ; typedef P1 Param1Type ; typedef NullType Param2Type ; } ; template struct FuncTrait { typedef R ReturnType ; typedef P1 Param1Type ; typedef P2 Param2Type ; } ; template class FuncHolder : public FuncImpl { public : explicit FuncHolder( const F& f ) : m_func( f ) { } FuncHolder* Clone() const { return new FuncHolder( *this ) ; } typedef typename FuncTrait::ReturnType ReturnType ; ReturnType operator()() { return m_func(); } ReturnType operator()( typename FuncTrait::Param1Type p1) { return m_func(p1); } ReturnType operator()( typename FuncTrait::Param1Type p1, typename FuncTrait::Param2Type p2) { return m_func(p1,p2); } private : F m_func ; } ; template struct NullFunc { typedef typename FuncTrait::ReturnType ReturnType ; ReturnType operator()() { return ReturnType() ; } ReturnType operator()( typename FuncTrait::Param1Type p1) { return ReturnType() ; } ReturnType operator()( typename FuncTrait::Param1Type p1, typename FuncTrait::Param2Type p2) { return ReturnType() ; } } ; template FuncHolder* MakeFuncHolder( F func ) { return new FuncHolder( func ) ; } } template class Function { public : Function( ) : m_pimpl( impl::MakeFuncHolder( impl::NullFunc() ) ) { } Function( const Function& f ) : m_pimpl( f.m_pimpl->Clone() ) { } template Function( const F& f ) : m_pimpl( impl::MakeFuncHolder( f ) ) { } Function& operator=( const Function& f ) { Function tmp( f ) ; std::swap( m_pimpl, tmp.m_pimpl ) ; return *this ; } ~Function( ) { } typedef typename impl::FuncTrait::ReturnType ReturnType ; ReturnType operator()( ) { return (*m_pimpl)() ; } template ReturnType operator()( P1 p1 ) { return (*m_pimpl)( p1 ) ; } template ReturnType operator()( P1 p1, P2 p2 ) { return (*m_pimpl)( p1, p2 ) ; } ; private : typedef impl::FuncImpl Impl ; std::unique_ptr m_pimpl ; } ; } // end of namespace