C ++/CLI의 기본 유형 목록을 기반으로 한 유형 세트를 생성하기위한 전처리 서자 라이브러리 부스트. C ++/CLI.
-
19-09-2019 - |
문제
Boost.processor 라이브러리를 사용하는 방법을 알아 내려고합니다. 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 ++ 템플릿에 대해 듣고 싶지 않습니다. 템플릿을 사용하는 방법을 알고 있습니다. 그러나 이것들은 제 경우에는 유용하지 않습니다. 예를 들어, 이러한 유형이 C#의 .NET에서 사용되지만 C ++/CLI에서 생성되고 있다고 상상해보십시오. 그러니 질문을 고수하십시오.
물론 문제는 .NET의 템플릿 지원 부족과 제네릭이 내 문제를 해결하기에 적합하지 않기 때문에 발생합니다.
해결책 3
Benoît의 답변을 바탕으로 다음 답변을 생각해 냈습니다. 답은 세 가지 파일로 구성됩니다.
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
MyPointyPeimpl.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 값 유형 IE를 상상해보십시오.
public value class Point
그런 다음 .NET EG C#에 사용할 모든 기본 숫자 유형의 포인트 유형을 효과적으로 만들었습니다.
다른 팁
오래된 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