VTK
dox/Common/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 vtkTryDowncastHelper
00052 {
00053 public:
00054   vtkTryDowncastHelper(vtkObject* source, FunctorT functor, bool& succeeded) :
00055     Source(source),
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     if(TargetT<ValueT>* const target = TargetT<ValueT>::SafeDownCast(Source))
00068       {
00069       Succeeded = true;
00070       this->Functor(target);
00071       }
00072   }
00073 
00074   vtkObject* Source;
00075   FunctorT Functor;
00076   bool& Succeeded;
00077 
00078 private:
00079   vtkTryDowncastHelper& operator=(const vtkTryDowncastHelper&);
00080 };
00081 
00082 template<template <typename> class TargetT, typename FunctorT, typename Arg1T>
00083 class vtkTryDowncastHelper1
00084 {
00085 public:
00086   vtkTryDowncastHelper1(vtkObject* source, FunctorT functor, Arg1T arg1, bool& succeeded) :
00087     Source(source),
00088     Functor(functor),
00089     Arg1(arg1),
00090     Succeeded(succeeded)
00091   {
00092   }
00093 
00094   template<typename ValueT>
00095   void operator()(ValueT) const
00096   {
00097     if(Succeeded)
00098       return;
00099 
00100     if(TargetT<ValueT>* const target = TargetT<ValueT>::SafeDownCast(Source))
00101       {
00102       Succeeded = true;
00103       this->Functor(target, this->Arg1);
00104       }
00105   }
00106 
00107   vtkObject* Source;
00108   FunctorT Functor;
00109   Arg1T Arg1;
00110   bool& Succeeded;
00111 
00112 private:
00113   vtkTryDowncastHelper1& operator=(const vtkTryDowncastHelper1&);
00114 };
00115 
00116 template<template <typename> class TargetT, typename TypesT, typename FunctorT>
00117 bool vtkTryDowncast(vtkObject* source, FunctorT functor)
00118 {
00119   bool succeeded = false;
00120   boost::mpl::for_each<TypesT>(vtkTryDowncastHelper<TargetT, FunctorT>(source, functor, succeeded));
00121   return succeeded;
00122 }
00123 
00124 template<template <typename> class TargetT, typename TypesT, typename FunctorT, typename Arg1T>
00125 bool vtkTryDowncast(vtkObject* source, FunctorT functor, Arg1T arg1)
00126 {
00127   bool succeeded = false;
00128   boost::mpl::for_each<TypesT>(vtkTryDowncastHelper1<TargetT, FunctorT, Arg1T>(source, functor, arg1, succeeded));
00129   return succeeded;
00130 }
00131