Kurbeln Preprocessor Bibliothek für einen Satz von Typen Erzeugen z.B. basierend auf einer Liste von Grundtypen PointI32, PointF32 usw. in C ++ / CLI

StackOverflow https://stackoverflow.com/questions/2222849

Frage

Ich versuche, herauszufinden, wie das Boost.Preprocessor Bibliothek http : //www.boost.org/doc/libs/release/libs/preprocessor eine „generische“ Art für verschiedene spezifische Typen zu entfalten. Im Folgenden werde ich für ein einfaches Point-Klasse Beispiel diese fragen. Gegeben:

struct Point##TYPE_SUFFIX_NAME
{
    TYPE X;
    TYPE Y;

    // Other code
};

Ich mag diese Art für verschiedene Grund (POD) Datentypen beispiels erzeugen.

PointF32, PointF64, PointI32 etc.

wo PointF32 wäre:

struct PointF32
{
     float X;
     float Y;
};

Das heißt, auf der Grundlage einer Liste von Typen:

short, int, long, float, double etc. 

Ich mag die oben genannte Art für diese „entfalten“. Vorzugsweise mit der „Vorlage“ Definition in einem separaten Include-Datei und nicht als Makro, für eine einfachere Fehlersuche zu ermöglichen.

Hinweis: Ich bin nicht daran interessiert zu hören, über C ++ Vorlagen. Ich weiß, wie Vorlagen. Aber diese sind nicht sinnvoll, in meinem Fall. Als ein Beispiel vorstellen, diese Art von .NET in C # verwendet werden, gehen, sondern werden in C ++ / CLI erzeugt. Halten Sie sich also bitte auf die Frage.

Das Problem ist natürlich, ergibt sich aus der fehlenden Vorlage Unterstützung in .NET und aufgrund Generika nicht geeignet ist, um mein Problem zu lösen.

War es hilfreich?

Lösung 3

Auf der Grundlage der Antwort von Benoît Ich habe mit der folgenden Antwort kommen. Die Antwort besteht aus drei Dateien:

  • 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"

Damit werden die Typen definieren:

PointI8, PointI16, PointI32, PointI64, 
PointUI8, PointUI16, PointUI32, PointUI64, 
PointF32, PointF64

Stellen Sie sich dann anstelle eines C ++ ein C ++ / CLI Wert Typ d.h struct:.

public value class Point 

Dann haben wir effektiv Punkttypen aller grundlegenden numerischen Typen für den Einsatz in .NET erstellt z.B. C #.

Andere Tipps

Alt (pre-Vorlage) Versionen von C ++ Compiler hatte oft einen <generic.h> Header für diese Art der Sache. Ich würde alte Versionen von g ++ danach suchen. Es war vor meiner Zeit, so dass ich weiß nicht, ob es Ihnen passen würde oder nicht.

Alternativ, so etwas wie

#define TYPE short
#define TYPES I16
#include "Point.def"
#undef TYPE
#undef TYPES
#define TYPE int
#define TYPES I32
#include "Point.def"

könnte auch Ihnen helfen.

oder offensichtlich ein externer Code-Generator (in awk, Perl, C ++, was auch immer). Das könnte die beste Lösung sein.

Der folgende Code ist ungetestet sollte aber ein guter Anfang zu machen, was passieren soll.

In 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

und in 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

Dies scheint eine alte Frage, aber .... Ich denke, einfacher ist es zu tun, nur mit dem Standard-Makroprozessor (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

Oder vielleicht diese Variante (die 'Spezifikationen' folgen)

#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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top