VTK
dox/Infovis/Boost/vtkTryDowncast.h
Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program:   Visualization Toolkit
00004   Module:    vtkTryDowncast.h
00005 
00006 -------------------------------------------------------------------------
00007   Copyright 2008 Sandia Corporation.
00008   Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00009   the U.S. Government retains certain rights in this software.
00010 -------------------------------------------------------------------------
00011 
00012   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
00013   All rights reserved.
00014   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
00015 
00016      This software is distributed WITHOUT ANY WARRANTY; without even
00017      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
00018      PURPOSE.  See the above copyright notice for more information.
00019 
00020 =========================================================================*/
00021 
00022 #include <vtkDenseArray.h>
00023 #include <vtkSmartPointer.h>
00024 #include <vtkSparseArray.h>
00025 
00026 #include <boost/mpl/for_each.hpp>
00027 #include <boost/mpl/joint_view.hpp>
00028 #include <boost/mpl/vector.hpp>
00029 
00030 // These are lists of standard VTK types.  End-users will have to choose these when they implement
00031 // their algorithms.
00032 
00033 // Description:
00034 // Enumerates all integer VTK types
00035 typedef boost::mpl::vector<vtkTypeUInt8, vtkTypeInt8, vtkTypeUInt16, vtkTypeInt16, vtkTypeUInt32, vtkTypeInt32, vtkTypeUInt64, vtkTypeInt64, vtkIdType> vtkIntegerTypes;
00036 // Description:
00037 // Enumerates all floating-point VTK types
00038 typedef boost::mpl::vector<vtkTypeFloat32, vtkTypeFloat64> vtkFloatingPointTypes;
00039 // Description:
00040 // Enumerates all numeric VTK types
00041 typedef boost::mpl::joint_view<vtkIntegerTypes, vtkFloatingPointTypes> vtkNumericTypes;
00042 // Description:
00043 // Enumerates all string VTK types
00044 typedef boost::mpl::vector<vtkStdString, vtkUnicodeString> vtkStringTypes;
00045 // Description:
00046 // Enumerates all VTK types
00047 typedef boost::mpl::joint_view<vtkNumericTypes, vtkStringTypes> vtkAllTypes;
00048 
00049 // End-users can ignore these, they're the guts of the beast ...
00050 template<template <typename> class TargetT, typename FunctorT>
00051 class vtkTryDowncastHelper1
00052 {
00053 public:
00054   vtkTryDowncastHelper1(vtkObject* source1, FunctorT functor, bool& succeeded) :
00055     Source1(source1),
00056     Functor(functor),
00057     Succeeded(succeeded)
00058   {
00059   }
00060 
00061   template<typename ValueT>
00062   void operator()(ValueT) const
00063   {
00064     if(Succeeded)
00065       return;
00066 
00067     TargetT<ValueT>* const target1 = TargetT<ValueT>::SafeDownCast(Source1);
00068     if(target1)
00069       {
00070       Succeeded = true;
00071       this->Functor(target1);
00072       }
00073   }
00074 
00075   vtkObject* Source1;
00076   FunctorT Functor;
00077   bool& Succeeded;
00078 
00079 private:
00080   vtkTryDowncastHelper1& operator=(const vtkTryDowncastHelper1&);
00081 };
00082 
00083 template<template <typename> class TargetT, typename FunctorT>
00084 class vtkTryDowncastHelper2
00085 {
00086 public:
00087   vtkTryDowncastHelper2(vtkObject* source1, vtkObject* source2, FunctorT functor, bool& succeeded) :
00088     Source1(source1),
00089     Source2(source2),
00090     Functor(functor),
00091     Succeeded(succeeded)
00092   {
00093   }
00094 
00095   template<typename ValueT>
00096   void operator()(ValueT) const
00097   {
00098     if(Succeeded)
00099       return;
00100 
00101     TargetT<ValueT>* const target1 = TargetT<ValueT>::SafeDownCast(Source1);
00102     TargetT<ValueT>* const target2 = TargetT<ValueT>::SafeDownCast(Source2);
00103     if(target1 && target2)
00104       {
00105       Succeeded = true;
00106       this->Functor(target1, target2);
00107       }
00108   }
00109 
00110   vtkObject* Source1;
00111   vtkObject* Source2;
00112   FunctorT Functor;
00113   bool& Succeeded;
00114 
00115 private:
00116   vtkTryDowncastHelper2& operator=(const vtkTryDowncastHelper2&);
00117 };
00118 
00119 template<template <typename> class TargetT, typename FunctorT>
00120 class vtkTryDowncastHelper3
00121 {
00122 public:
00123   vtkTryDowncastHelper3(vtkObject* source1, vtkObject* source2, vtkObject* source3, FunctorT functor, bool& succeeded) :
00124     Source1(source1),
00125     Source2(source2),
00126     Source3(source3),
00127     Functor(functor),
00128     Succeeded(succeeded)
00129   {
00130   }
00131 
00132   template<typename ValueT>
00133   void operator()(ValueT) const
00134   {
00135     if(Succeeded)
00136       return;
00137 
00138     TargetT<ValueT>* const target1 = TargetT<ValueT>::SafeDownCast(Source1);
00139     TargetT<ValueT>* const target2 = TargetT<ValueT>::SafeDownCast(Source2);
00140     TargetT<ValueT>* const target3 = TargetT<ValueT>::SafeDownCast(Source3);
00141     if(target1 && target2 && target3)
00142       {
00143       Succeeded = true;
00144       this->Functor(target1, target2, target3);
00145       }
00146   }
00147 
00148   vtkObject* Source1;
00149   vtkObject* Source2;
00150   vtkObject* Source3;
00151   FunctorT Functor;
00152   bool& Succeeded;
00153 
00154 private:
00155   vtkTryDowncastHelper3& operator=(const vtkTryDowncastHelper3&);
00156 };
00157 
00158 template<template <typename> class TargetT, typename TypesT, typename FunctorT>
00159 bool vtkTryDowncast(vtkObject* source1, FunctorT functor)
00160 {
00161   bool succeeded = false;
00162   boost::mpl::for_each<TypesT>(vtkTryDowncastHelper1<TargetT, FunctorT>(source1, functor, succeeded));
00163   return succeeded;
00164 }
00165 
00166 template<template <typename> class TargetT, typename TypesT, typename FunctorT>
00167 bool vtkTryDowncast(vtkObject* source1, vtkObject* source2, FunctorT functor)
00168 {
00169   bool succeeded = false;
00170   boost::mpl::for_each<TypesT>(vtkTryDowncastHelper2<TargetT, FunctorT>(source1, source2, functor, succeeded));
00171   return succeeded;
00172 }
00173 
00174 
00175 template<template <typename> class TargetT, typename TypesT, typename FunctorT>
00176 bool vtkTryDowncast(vtkObject* source1, vtkObject* source2, vtkObject* source3, FunctorT functor)
00177 {
00178   bool succeeded = false;
00179   boost::mpl::for_each<TypesT>(vtkTryDowncastHelper3<TargetT, FunctorT>(source1, source2, source3, functor, succeeded));
00180   return succeeded;
00181 }
00182 
00183 // VTK-HeaderTest-Exclude: vtkTryDowncast.h