基本型のリストに基づいて型のセットを生成するための Boost プリプロセッサ ライブラリ。PointI32、PointF32などC++/CLI で
-
19-09-2019 - |
質問
Boost.Preprocessorライブラリの使用方法を理解しようとしています http://www.boost.org/doc/libs/release/libs/preprocessor さまざまな特定のタイプの「ジェネリック」タイプを展開します。以下では、簡単なポイントクラスの例について質問します。与えられる:
struct Point##TYPE_SUFFIX_NAME
{
TYPE X;
TYPE Y;
// Other code
};
さまざまな基本 (POD) データ型に対してこの型を生成したいと考えています。例:
PointF32, PointF64, PointI32 etc.
ここで、PointF32 は次のようになります。
struct PointF32
{
float X;
float Y;
};
つまり、タイプのリストに基づいて次のようになります。
short, int, long, float, double etc.
これらに対して上記のタイプを「展開」したいと思います。デバッグを容易にするために、マクロとしてではなく、別のインクルード ファイルに「テンプレート」定義を含めることをお勧めします。
注記:C++ テンプレートについて聞くことに興味はありません。テンプレートの使い方を知っています。しかし、これらは私の場合には役に立ちません。例として、これらの型が .NET から C# で使用され、生成されるのは C++/CLI であると想像してください。それでは、質問を続けてください。
もちろん、この問題は、.NET でのテンプレート サポートの欠如と、ジェネリックが問題の解決に適していないことが原因で発生します。
解決 3
Benoit氏の回答に基づいて、私は次の答えを思いつきました。答えは 3 つのファイルで構成されます。
MyPointTypes.h
MyPointTypeImpl.h
MyPointTypes.cpp
MyPointTypes.h:
#ifndef __MYSTRUCTURES_H__
#define __MYSTRUCTURES_H__
#include <boost/preprocessor/iteration/iterate.hpp>
#include <boost/preprocessor/seq/size.hpp>
typedef signed char int8;
typedef unsigned char uint8;
typedef signed short int16;
typedef unsigned short uint16;
typedef signed int int32;
typedef unsigned int uint32;
typedef signed int int64;
typedef unsigned int uint64;
typedef float float32;
typedef double float64;
#define MY_SIGNED_INTEGER_SEQ (int8)(int16)(int32)(int64)
#define MY_SIGNED_INTEGER_SUFFIX_SEQ (I8)(I16)(I32)(I64)
#define MY_UNSIGNED_INTEGER_SEQ (uint8)(uint16)(uint32)(uint64)
#define MY_UNSIGNED_INTEGER_SUFFIX_SEQ (UI8)(UI16)(UI32)(UI64)
#define MY_SIGNED_UNSIGNED_INTEGER_SEQ MY_SIGNED_INTEGER_SEQ MY_UNSIGNED_INTEGER_SEQ
#define MY_SIGNED_UNSIGNED_INTEGER_SUFFIX_SEQ MY_SIGNED_INTEGER_SUFFIX_SEQ MY_UNSIGNED_INTEGER_SUFFIX_SEQ
#define MY_FLOAT_SEQ (float32)(float64)
#define MY_FLOAT_SUFFIX_SEQ (F32)(F64)
#define MY_BASIC_NUMERIC_TYPES_SEQ MY_SIGNED_UNSIGNED_INTEGER_SEQ MY_FLOAT_SEQ
#define MY_BASIC_NUMERIC_TYPES_SUFFIX_SEQ MY_SIGNED_UNSIGNED_INTEGER_SUFFIX_SEQ MY_FLOAT_SUFFIX_SEQ
#define MY_SEQ_OF_TYPES MY_BASIC_NUMERIC_TYPES_SEQ
#define MY_SEQ_OF_SUFFICES MY_BASIC_NUMERIC_TYPES_SUFFIX_SEQ
#define BOOST_PP_ITERATION_LIMITS (0, BOOST_PP_SEQ_SIZE(MY_SEQ_OF_TYPES) - 1)
#include BOOST_PP_ITERATE()
#undef MY_SEQ_OF_TYPES
#undef MY_SEQ_OF_SUFFICES
#endif
MyPointTypeImpl.h:
#include <boost/preprocessor/seq/elem.hpp>
#define n BOOST_PP_ITERATION()
#define PASTER(x,y) x ## y
#define EVALUATOR(x,y) PASTER(x,y)
#define CONCATEVALUATED(x, y) EVALUATOR(x, y)
#define TYPE BOOST_PP_SEQ_ELEM(n, MY_SEQ_OF_TYPES)
#define SUFFIX BOOST_PP_SEQ_ELEM(n, MY_SEQ_OF_SUFFICES)
#define ADDSUFFIX(cls) CONCATEVALUATED(cls, SUFFIX)
struct ADDSUFFIX(Point)
{
TYPE X;
TYPE Y;
};
#undef n
MyPointTypes.cpp:
#define BOOST_PP_FILENAME_1 "MyPointTypeImpl.h"
#include "MyPointTypes.h"
これにより、タイプが定義されます。
PointI8, PointI16, PointI32, PointI64,
PointUI8, PointUI16, PointUI32, PointUI64,
PointF32, PointF64
次に、C++ 構造体の代わりに C++/CLI 値型を想像してください。つまり、次のようになります。
public value class Point
次に、.NET で使用するすべての基本的な数値型のポイント型を効果的に作成しました。C#。
他のヒント
の旧の(前のテンプレート)のバージョンは、多くの場合、事のような種類のための<generic.h>
ヘッダを持っていました。私はそれのためのG ++の古いバージョンを検索したいです。それは私の時間の前にあったので、それはあなたに合うかどうかどうかは分かりません。
また、のようなもの。
#define TYPE short
#define TYPES I16
#include "Point.def"
#undef TYPE
#undef TYPES
#define TYPE int
#define TYPES I32
#include "Point.def"
また、あなたを助けることができます。
または明らかに外部のコード・ジェネレータ(AWKで、Perlの、C ++、何でも)。それは最善の解決策になる可能性があります。
次のコードは、をテストしていないのですが、あなたが起こるしたいものを作るために良いスタートである必要があります。
my_structures.hでます:
#ifndef __MYSTRUCTURES_H__
#define __MYSTRUCTURES_H__
#define MY_LIST_OF_TYPES (F32, (I32, (BOOST_PP_NIL)))
#define MY_LIST_OF_SUFFICES (float, (int, (BOOST_PP_NIL)))
#include <boost/preprocessor/iteration/iterate.hpp>
#include <boost/preprocessor/list/size.hpp>
#define BOOST_PP_ITERATION_LIMITS (0, BOOST_PP_LIST_SIZE(MY_LIST_OF_TYPES))
#define BOOST_PP_FILENAME_1 "create_my_structures.h"
#include BOOST_PP_ITERATE()
#undef MY_LIST_OF_TYPES
#undef MY_LIST_OF_SUFFICES
#endif
とcreate_my_structures.hで
#include <boost/preprocessor/list/at.hpp>
#define n BOOST_PP_ITERATION()
struct Point ## BOOST_PP_LIST_AT(MY_LIST_OF_SUFFICES, n)
{
BOOST_PP_LIST_AT(MY_LIST_OF_TYPES, n) X;
BOOST_PP_LIST_AT(MY_LIST_OF_TYPES, n) Y;
};
#undef n
この古い質問だけど.... 私は、標準マクロプロセッサ(CPP)でそれを行うことが容易だと思います。
#define STRUCT_POINT( P_TYPE ) \
struct Point##_##P_TYPE \
{ \
P_TYPE X; \
P_TYPE Y; \
\
};
#define CREATE_STRUCT_POINTS \
STRUCT_POINT( short ) \
STRUCT_POINT( int ) \
STRUCT_POINT( unsigned ) \
STRUCT_POINT( float ) \
STRUCT_POINT( double )
CREATE_STRUCT_POINTS
#undef CREATE_STRUCT_POINTS
#undef STRUCT_POINT
それとも、この変化( '仕様' を従うために)
#define STRUCT_POINT( P_TYPE, P_TYPE_ALIAS ) \
struct Point##P_TYPE_ALIAS \
{ \
P_TYPE X; \
P_TYPE Y; \
\
};
#define CREATE_STRUCT_POINTS \
STRUCT_POINT( short , I16 ) \
STRUCT_POINT( int , I32 ) \
STRUCT_POINT( unsigned , U32 ) \
STRUCT_POINT( float , F32 ) \
STRUCT_POINT( double , F64 )
CREATE_STRUCT_POINTS
#undef CREATE_STRUCT_POINTS
#undef STRUCT_POINT