2016-04-07 10 views
0

VTKには基本型(float、int、doubleなど)のtypedefがあり、型ごとの整数が割り当てられます。 hereと指定されています。vtkデータ型と基本データ型の比較

GetDataType()は、たとえばvtkDataArrayのいずれかの型に対応する整数を返します。 その整数を基本データ型(float、int、double)と比較したいと思います。

簡単な方法はありますか?

私が使っているのは、パラメータTがスカラーのテンプレートクラスです。 私は、データセットのスカラーポイントデータは、私が何をすべきか、今のT.

と同じデータ型を持つ型のサイズ比較であるかどうかを確認したい:

vtkDataArray *scalars = image->GetPointData()->GetScalars(); 
if(scalars->GetDataTypeSize() != sizeof(T)) 
{ 
    std::cerr<<"Incompatible types"<<std::endl; 
} 

しかし、明らかに、floatintは両方ともサイズ4なので、実際には機能しません。

アイデア?

+0

私はいくつかの例を準備しています... – norisknofun

答えて

0

いくつかの場所から情報を収集した後、2つのタイプのリスト間のマッピングを自分で作成することなく、簡単に書き込む方法がないと結論づけました。

だから、ここで私はそれを行うために見出される最もエレガントな方法です:

私はnorisknofunのマップのアイデアを使用し、私はそれを反転。 typeid()の結果から直接hash_codeを取得できると思われるので、私はstd::type_index()を使用しませんでした。 基本的な型をVTK型に変換する関数にこのマッピングを置くのは、単に比較以外の目的に役立つからです(私のother post参照)。

したがって
#include <vtkType.h> 

int GetVTKType(std::size_t hash_code) 
{ 
    static std::map<std::size_t, long> typeMap; 
    if(typeMap.empty()) 
    { 
     typeMap[typeid(void).hash_code()]    = VTK_VOID; 
     typeMap[typeid(char).hash_code()]    = VTK_CHAR; 
     typeMap[typeid(signed char).hash_code()]  = VTK_SIGNED_CHAR; 
     typeMap[typeid(unsigned char).hash_code()]  = VTK_UNSIGNED_CHAR; 
     typeMap[typeid(short).hash_code()]    = VTK_SHORT; 
     typeMap[typeid(unsigned short).hash_code()]  = VTK_UNSIGNED_SHORT; 
     typeMap[typeid(int).hash_code()]    = VTK_INT; 
     typeMap[typeid(unsigned int).hash_code()]  = VTK_UNSIGNED_INT; 
     typeMap[typeid(long).hash_code()]    = VTK_LONG; 
     typeMap[typeid(unsigned long).hash_code()]  = VTK_UNSIGNED_LONG; 
     typeMap[typeid(float).hash_code()]    = VTK_FLOAT; 
     typeMap[typeid(double).hash_code()]    = VTK_DOUBLE; 
     typeMap[typeid(std::string).hash_code()]  = VTK_STRING; 
     typeMap[typeid(long long).hash_code()]   = VTK_LONG_LONG; 
     typeMap[typeid(unsigned long long).hash_code()] = VTK_UNSIGNED_LONG_LONG; 
     typeMap[typeid(int64_t).hash_code()]   = VTK___INT64; 
     typeMap[typeid(uint64_t).hash_code()]   = VTK_UNSIGNED___INT64; 
    } 
    return typeMap[hash_code]; 
} 

、VTKのデータ型を比較す​​ると、基本型(私のテンプレートパラメータT)、私は:

vtkDataArray *scalars = image->GetPointData()->GetScalars(); 
if(scalars->GetDataType() != GetVTKType(typeid(T).hash_code())) 
{ 
    std::cerr<<"Incompatible types"<<std::endl; 
} 

それともnorisknofunが行ったように私は素敵な比較機能が必要な場合それは私ができる:

template < class T > 
bool is_same(long vtkType) 
{ 
    return vtkType != GetVTKType(typeid(T).hash_code()) 
} 

// somewhere.cpp 
if(!is_same<T>(scalars->GetDataType())) 
{ 
    std::cerr<<"Incompatible types"<<std::endl; 
} 
0

私はあなた自身のマッピングを精緻化しなければならないと思います。あなたのコンパイラはRTTIでC++ 11に準拠していなければなりませんが、現代のコンパイラのほとんどがこの機能をサポートしています。あなたの場合、私は 'ビット'、 'ID_TYPE' と '不透明' なタイプのC++と同等であるものを知らない

...

#include <iostream> 
#include <typeinfo> 
#include <typeindex> 
#include <cstdint> 
#include <string> 
#include <map> 

// copy from vtk header, use #include <vtkType.h> instead 
#define VTK_VOID   0 
#define VTK_BIT    1 
#define VTK_CHAR   2 
#define VTK_SIGNED_CHAR 15 
#define VTK_UNSIGNED_CHAR 3 
#define VTK_SHORT   4 
#define VTK_UNSIGNED_SHORT 5 
#define VTK_INT    6 
#define VTK_UNSIGNED_INT 7 
#define VTK_LONG   8 
#define VTK_UNSIGNED_LONG 9 
#define VTK_FLOAT   10 
#define VTK_DOUBLE   11 
#define VTK_ID_TYPE  12 
#define VTK_STRING   13 
#define VTK_OPAQUE   14 
#define VTK_LONG_LONG   16 
#define VTK_UNSIGNED_LONG_LONG 17 
#define VTK___INT64   18 
#define VTK_UNSIGNED___INT64 19 

// vtktypes 
    typedef long vtktypes ; 

    // standard c++ types 
    typedef std::size_t mytypes ; 
    typedef std::map< vtktypes, mytypes> map_t; 

template < class T > 
bool is_same(vtktypes x) 
{ 
    static std::map< vtktypes, mytypes> _map; 
    if(_map.empty()) 
    { 
     _map[VTK_VOID   ] = std::type_index(typeid(void)).hash_code(); 
     //_map[VTK_BIT    ] = std::type_index(typeid(void)).hash_code(); 
     _map[VTK_CHAR   ] = std::type_index(typeid(char)).hash_code(); 
     _map[VTK_SIGNED_CHAR ] = std::type_index(typeid(signed char)).hash_code(); 
     _map[VTK_UNSIGNED_CHAR ] = std::type_index(typeid(unsigned char)).hash_code(); 
     _map[VTK_SHORT   ] = std::type_index(typeid(short)).hash_code(); 
     _map[VTK_UNSIGNED_SHORT ] = std::type_index(typeid(unsigned short)).hash_code(); 
     _map[VTK_INT   ] = std::type_index(typeid(int)).hash_code(); 
     _map[VTK_UNSIGNED_INT ] = std::type_index(typeid(unsigned int)).hash_code(); 
     _map[VTK_LONG   ] = std::type_index(typeid(long)).hash_code(); 
     _map[VTK_UNSIGNED_LONG ] = std::type_index(typeid(unsigned long)).hash_code(); 
     _map[VTK_FLOAT   ] = std::type_index(typeid(float)).hash_code(); 

     _map[VTK_DOUBLE   ] = std::type_index(typeid(double)).hash_code(); 
     //_map[VTK_ID_TYPE   ] = type_index(typeid()).hash_code(); 
     _map[VTK_STRING   ] = std::type_index(typeid(std::string)).hash_code(); 
     //_map[VTK_OPAQUE   ] = type_index(typeid(void)).hash_code(); 
     _map[VTK_LONG_LONG   ]= std::type_index(typeid(long long)).hash_code(); 
     _map[VTK_UNSIGNED_LONG_LONG]= std::type_index(typeid(unsigned long long)).hash_code(); 
     _map[VTK___INT64   ]= std::type_index(typeid(int64_t)).hash_code(); 
     _map[VTK_UNSIGNED___INT64 ]= std::type_index(typeid(uint64_t)).hash_code(); 
    } 

    map_t::iterator it = _map.find(x); 
    return (it != _map.end()) && it->second == std::type_index(typeid(T)).hash_code(); 
} 

int main() 
{ 
    std::cout << "is same ? " << is_same<char>(2) << std::endl ; 
    std::cout << "is same ? " << is_same<std::string>(13) << std::endl ;  

    return 0; 
} 

、あなたはそのようにそれを使用することができます:

vtkDataArray *scalars = image->GetPointData()->GetScalars(); 
if(!is_same<T>(scalars->GetDataTypeSize())) 
{ 
    std::cerr<<"Incompatible types"<<std::endl; 
}