⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 variant_cc.h

📁 The goal of this library is to make ODBC recordsets look just like an STL container. As a user, you
💻 H
📖 第 1 页 / 共 2 页
字号:
// (C) 2000, Fernando Luis Cacciola Carballal.
//
// This material is provided "as is", with absolutely no warranty expressed
// or implied. Any use is at your own risk.
//
// Permission to use or copy this software for any purpose is hereby granted
// without fee, provided the above notices are retained on all copies.
// Permission to modify the code and to distribute modified code is granted,
// provided the above notices are retained, and a notice that the code was
// modified is included with the above copyright notice.
//
// You are welcome to contact the author at: fcacciola@fibertel.com.ar

#ifndef VARIANT_CC_H
#define VARIANT_CC_H

#include "DB_Base.h"
#include "Callback.h"
#include "VariantException.h"
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
using namespace std;

BEGIN_DTL_NAMESPACE
//
// NOTE: The following conditional compilation macros will change the interface
// for variant_cc_t.
//

// NO_EXPLICIT_MEMBER_TPL_INSTANTIATION :
//
// Some compilers fail to explicitely instantiate member template functions:
// They won't compile: int n = my_variant.get<int>()
// One solution is to add an extra dummy argument to help name lookup.
//
// If NO_EXPLICIT_MEMBER_TPL_INSTANTIATION is defined, some methods will have this
// extra argument. This extra argument is not used so it is declared as a const* so
// you can pass (T cosnt*)NULL.
//

#define NO_EXPLICIT_MEMBER_TPL_INSTANTIATION

#ifdef _MSC_VER
  #pragma warning(disable: 4800) // 'int' : forcing value to bool 'true' or 'false' (performance warning)
#endif

// Class variant_cc_t
// This is a variation of variant_cc_t.
// It implements a 'copy on copy' scheme: that is,
// each time a variant_cc_t is copied it internal
// data is copied too.
// This avoids the shared implementation at the cost of
// copying the value held.
//
// Those portions of this code which differ from variant_cc_t
// have a comment.
//
// Mar 2000, Fernando Luis Cacciola Carballal.
//
//  26/09/2000 FLC (T v) arguments changed to (T const& v).
//  26/09/2000 FLC std:: added to throw expresion.
//  27/09/2000 FLC MSVC changes.
//                   * NO_EXPLICIT_MEMBER_TPL_INSTANTIATION conditional compilation added.
//                   * One of the 'is_type' methods was renamed to 'is_type_as'
//                       to avoid overload resolution problems.
class variant_cc_t
{
private:
	// Don't allow default constructor -- too dangerous
    // Too easy to end up with functions pointing into NULL objects
	// Let the compiler help us at compile time by forbidding default construction
    variant_cc_t() : data ( NULL ) {} 
public :


    template<typename T> variant_cc_t ( T const& v )
      : data ( new Impl<T>(v) )
      {}

    // * Copy the internal data instead of sharing it.
    variant_cc_t( const variant_cc_t & rhs )
      : data ( rhs.data != NULL ? rhs.data->clone()
                                : NULL
             )
      {}

    // No need to test for concurrent users.
   ~variant_cc_t()
      { delete data ; }

    void swap(variant_cc_t &other)
	{
		std::swap(data, other.data);
	}

    // * Copy the internal data instead of sharing it.
    variant_cc_t& operator = ( const variant_cc_t& rhs )
	{
		if (this != &rhs)
		{
			variant_cc_t tmp(rhs);
		    swap(tmp);
		}

        return * this ;
    }

    template<typename T> operator T () const
      { return CastFromBase<T>( data )->data ; }

    #ifdef NO_EXPLICIT_MEMBER_TPL_INSTANTIATION
    template<typename T> const T & get( T const* dmy =NULL ) const
      { return CastFromBase( data , dmy )->data ; }
    #else
    template<typename T> const T & get() const
      { return CastFromBase<T>( data )->data ; }
    #endif

    #ifdef NO_EXPLICIT_MEMBER_TPL_INSTANTIATION
    template<typename T> bool is_type() const
    #else
    template<typename T> bool is_type() const
    #endif
      { return typeid(*data)==typeid(Impl<T>); }

    template<typename T> bool is_type_as(T const& v) const
      { return typeid(*data)==typeid(v); }
    template<typename T> bool is_type_as(T const* v) const
      { return typeid(*data)==typeid(v); }

	// need versions for 0,1,2,3,4 params with or without return values

	// *** register a functor for the object ***
	
	// first, we need versions for non-const member functions
	template<class T> void AddCBFunctor0(const int &funcName,
		 void (T::*func) (void))
	{
		CBFunctor((CBFunctor0 *)NULL, (T *) NULL, funcName, func);
	}

	template<class T, class P1> void AddCBFunctor1(const int &funcName,
		  void (T::*func) (P1))
	{
		CBFunctor((CBFunctor1<P1> *)NULL, (T *) NULL, funcName, func);
	}

	template<class T, class P1, class P2> void AddCBFunctor2(const int &funcName,
		  void (T::*func) (P1, P2))
	{
		CBFunctor((CBFunctor2<P1, P2> *)NULL, (T *) NULL, funcName, func);
	}

	template<class T, class P1, class P2, class P3> 
		  void AddCBFunctor3(const int &funcName, void (T::*func) (P1, P2, P3))
	{
		CBFunctor((CBFunctor3<P1, P2, P3> *)NULL, (T *) NULL, funcName, func);
	}

	template<class T, class P1, class P2, class P3, class P4> void 
		  AddCBFunctor4(const int &funcName, void (T::*func) (P1, P2, P3, P4))
	{
		CBFunctor((CBFunctor4<P1, P2, P3, P4> *)NULL, (T *) NULL, funcName, func);
	}

	template<class T, class RT> void AddCBFunctor0_w_ret(const int &funcName,
		  RT (T::*func) (void))
	{
		CBFunctor((CBFunctor0wRet<RT> *)NULL, (T *) NULL, funcName, func);
	}

	template<class T, class P1, class RT> void AddCBFunctor1_w_ret(const int &funcName,
		  RT (T::*func) (P1))
    {
		CBFunctor((CBFunctor1wRet<P1, RT> *)NULL, (T *) NULL, funcName, func);
	}

	template<class T, class P1, class P2, class RT> void AddCBFunctor2_w_ret(const int &funcName,
		  RT (T::*func) (P1, P2))
    {
		CBFunctor((CBFunctor2wRet<P1, P2, RT> *)NULL, (T *) NULL, funcName, func);
    }

	template<class T, class P1, class P2, class P3, class RT> 
		  void AddCBFunctor3_w_ret(const int &funcName,
		  RT (T::*func) (P1, P2, P3))
    {
		CBFunctor((CBFunctor3wRet<P1, P2, P3, RT> *)NULL, (T *) NULL, funcName, func);
	}

	template<class T, class P1, class P2, class P3, class P4, class RT>
		  void AddCBFunctor4_w_ret(const int &funcName,
		  RT (T::*func) (P1, P2, P3, P4))
    {
		CBFunctor((CBFunctor4wRet<P1, P2, P3, P4, RT> *)NULL, (T *) NULL, funcName, func);
    }

    // also need versions for const member functions
	template<class T> void AddCBFunctor0(const int &funcName,
		 void (T::*func) (void) const)
	{

		CBFunctor((CBFunctor0 *)NULL, (T *) NULL, funcName, func);
	}

	template<class T, class P1> void AddCBFunctor1(const int &funcName,
		  void (T::*func) (P1) const)
	{
		CBFunctor((CBFunctor1<P1> *)NULL, (T *) NULL, funcName, func);
	}

	template<class T, class P1, class P2> void AddCBFunctor2(const int &funcName,
		  void (T::*func) (P1, P2) const)
	{
		CBFunctor((CBFunctor2<P1, P2> *)NULL, (T *) NULL, funcName, func);
	}

	template<class T, class P1, class P2, class P3> 
		  void AddCBFunctor3(const int &funcName, void (T::*func) (P1, P2, P3) const)
	{
		CBFunctor((CBFunctor3<P1, P2, P3> *)NULL, (T *) NULL, funcName, func);
	}

	template<class T, class P1, class P2, class P3, class P4> void 
		  AddCBFunctor4(const int &funcName, void (T::*func) (P1, P2, P3, P4) const)
	{
		CBFunctor((CBFunctor4<P1, P2, P3, P4> *)NULL, (T *) NULL, funcName, func);
	}

	template<class T, class RT> void AddCBFunctor0_w_ret(const int &funcName,
		  RT (T::*func) (void) const)
	{
		CBFunctor((CBFunctor0wRet<RT> *)NULL, (T *) NULL, funcName, func);
	}

	template<class T, class P1, class RT> void AddCBFunctor1_w_ret(const int &funcName,
		  RT (T::*func) (P1) const)
    {
		CBFunctor((CBFunctor1wRet<P1, RT> *)NULL, (T *) NULL, funcName, func);
	}

	template<class T, class P1, class P2, class RT> void AddCBFunctor2_w_ret(const int &funcName,
		  RT (T::*func) (P1, P2) const)
    {
		CBFunctor((CBFunctor2wRet<P1, P2, RT> *)NULL, (T *) NULL, funcName, func);
    }

	template<class T, class P1, class P2, class P3, class RT> 
		  void AddCBFunctor3_w_ret(const int &funcName,
		  RT (T::*func) (P1, P2, P3) const)
    {
		CBFunctor((CBFunctor3wRet<P1, P2, P3, RT> *)NULL, (T *) NULL, funcName, func);
	}

	template<class T, class P1, class P2, class P3, class P4, class RT>
		  void AddCBFunctor4_w_ret(const int &funcName,
		  RT (T::*func) (P1, P2, P3, P4) const)
    {
		CBFunctor((CBFunctor4wRet<P1, P2, P3, P4, RT> *)NULL, (T *) NULL, funcName, func);
    }


	// get a pointer to the FunctorBase for this variant
	CBFunctorBase *GetFunctorBase(const int &funcName) const
	{
		return data->GetFunctorBase(funcName);
	}

 
  private :

	// helper function that rips apart the actual types and records the
	// functor under the funcName passed in
	template <class T, class CBFunctorType, class Func> 
		void CBFunctor(CBFunctorType *pcbt, T *dummy, const int &funcName, Func func) {
		Impl<T>* p = dynamic_cast<Impl<T>*> ( data ) ;

		if (p == NULL)
			throw VariantException("variant_cc_t::CBFunctor()",
			   "dynamic cast failed: function is not a member of this object");

		CBFunctorBase *pFbase = new CBFunctorType(
			       makeFunctor((CBFunctorType *) 0, p->data , func)
				 );
		data->AddCBFunctor(funcName, pFbase);
	}

    // This version has a clone() method so copies
    // of particular Impl<> can be obtained.
    struct ImplBase
    {
	  typedef pair<int, CBFunctorBase *> CallbackPair;

	  typedef vector<CallbackPair> MethodList;

	  MethodList methods; // vector of callback id, func
	  
	  ImplBase() : methods() {}

	  // need to delete the CBFunctorBase objects
      virtual ~ImplBase () 
	  {
		 for (MethodList::iterator it = methods.begin(); it != methods.end(); it++)
		 {
			CallbackPair &pr = *it;

			delete pr.second;
			pr.second = NULL;
		 }
	  
	  }

	  virtual  ImplBase* clone() const = 0 ;

      MethodList::iterator find_func(const int &funcName) const {
      
           ImplBase *this_ptr = const_cast<ImplBase *>(this); 
    	   MethodList::iterator it_end = this_ptr->methods.end();
		   MethodList::iterator it = this_ptr->methods.begin();
		  
		   for ( ; it != it_end; ++it)
			{
				if ((*it).first == funcName)
				   break;
		
			}

		   if (it == it_end)
			   throw VariantException("variant_cc_t::ImplBase::find_func()", "No such method registered!");

		   return it;
	  }

	  // gets a pointer to FunctorBase for the funcName passed in
	  // returns NULL if none found
	  CBFunctorBase *GetFunctorBase(const int &funcName) const
	  {

		   // finds and returns the CBFunctorBase * with the given funcName
		   MethodList::const_iterator it;
		   
		   try
		   {
			  it = find_func(funcName);
			  return (*it).second;
		   }
		   catch (...)
		   {

		   }
		   return NULL; // suppress warnings
	  }

	  // registers a functor with the given name in a typeless manner
	  void AddCBFunctor(const int &funcName, CBFunctorBase *pFbase)
	  {
		methods.push_back(CallbackPair(funcName, pFbase));
	  }


    } ;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -