Zähl-Makro?
-
Variadische Templates braucht das nicht, aber variadische Makros, die einige Compiler (*hust* MSVC *hust*) nicht so richtig beherrschen. Du kannst aber auch direkt eine Boost.PP-Sequenz benutzen:
#include <boost/preprocessor/seq/for_each.hpp> #define DEF_VALUE( num, data, name ) const unsigned name = 1 << ( num - 2 ); #define DEF_VALUES(seq) BOOST_PP_SEQ_FOR_EACH( DEF_VALUE, _, seq) DEF_VALUES( (FILE_READ) (FILE_WRITE) (FILE_COPY_ON_WRITE) (FILE_SEQUENTIAL) (FILE_TEMPORARY) )
Sieht nicht ganz so hübsch aus, aber läuft.
-
volkard schrieb:
Leider klappt folgendes nicht auf jedem Compiler:
#define LINESTART __LINE__ #define FILE_READ (1<<(__LINE__-LINESTART)) #define FILE_WRITE (1<<(__LINE__-LINESTART)) #define FILE_COPY_ON_WRITE (1<<(__LINE__-LINESTART)) #define FILE_SEQUENTIAL (1<<(__LINE__-LINESTART)) #define FILE_TEMPORARY (1<<(__LINE__-LINESTART))
LINESTART ist dann auf machen als 34 definiert und auf manchen als __LINE__ definiert.
Compiler, auf denen das nicht klappt, implementieren Makros richtig. Makros werden erst im Body expandiert.
-
volkard schrieb:
Leider klappt folgendes nicht auf jedem Compiler:
#define LINESTART __LINE__ #define FILE_READ (1<<(__LINE__-LINESTART)) #define FILE_WRITE (1<<(__LINE__-LINESTART)) #define FILE_COPY_ON_WRITE (1<<(__LINE__-LINESTART)) #define FILE_SEQUENTIAL (1<<(__LINE__-LINESTART)) #define FILE_TEMPORARY (1<<(__LINE__-LINESTART))
LINESTART ist dann auf machen als 34 definiert und auf manchen als __LINE__ definiert.
Was spricht gegen:
constexpr std::size_t LINESTART = __LINE__;
?
-
Nathan schrieb:
volkard schrieb:
Leider klappt folgendes nicht auf jedem Compiler:
#define LINESTART __LINE__ #define FILE_READ (1<<(__LINE__-LINESTART)) #define FILE_WRITE (1<<(__LINE__-LINESTART)) #define FILE_COPY_ON_WRITE (1<<(__LINE__-LINESTART)) #define FILE_SEQUENTIAL (1<<(__LINE__-LINESTART)) #define FILE_TEMPORARY (1<<(__LINE__-LINESTART))
LINESTART ist dann auf machen als 34 definiert und auf manchen als __LINE__ definiert.
Was spricht gegen:
constexpr std::size_t LINESTART = __LINE__;
?
Gut.
Dann muss man die anderen aber auch alle mit constexpr machen und hat gar kein #define mehr.Hmm, wenn wir soweit gehen, tuts ja sogar ein enum.
#include <iostream> enum FILEMODE{ LINESTART = __LINE__, FILE_READ = (1<<(__LINE__-LINESTART-1)), FILE_WRITE = (1<<(__LINE__-LINESTART-1)), FILE_COPY_ON_WRITE = (1<<(__LINE__-LINESTART-1)), FILE_SEQUENTIAL = (1<<(__LINE__-LINESTART-1)), FILE_TEMPORARY = (1<<(__LINE__-LINESTART-1)), }; int main(){ std::cout<<FILE_WRITE<<'\n'; std::cout<<FILE_READ<<'\n'; }
oder
#include <iostream> #define BEGINFLAGS _line_start = __LINE__ #define NEXTFLAG (1<<(__LINE__-_line_start-1)) enum file_mode{ BEGINFLAGS, read = NEXTFLAG, write = NEXTFLAG, copy_on_write = NEXTFLAG, sequential = NEXTFLAG, temporary = NEXTFLAG, }; int main(){ std::cout<<file_mode::write<<'\n'; std::cout<<file_mode::read<<'\n'; }
-
Selbst wenn man das noch mit einer Enumeration hinschustert, finde ich das hässlich. Wieso nicht einfach direkt hinschreiben... alles andere ist doch Overkill.
-
enum FILEMODE{ LINESTART = __LINE__, FILE_READ = (1<<(__LINE__-LINESTART-1)), FILE_WRITE = (1<<(__LINE__-LINESTART-1)), FILE_COPY_ON_WRITE = (1<<(__LINE__-LINESTART-1)), FILE_SEQUENTIAL = (1<<(__LINE__-LINESTART-1)), FILE_TEMPORARY = (1<<(__LINE__-LINESTART-1)), }; // vs enum FILEMODE { FILE_READ = 1, FILE_WRITE = 1 << 1, FILE_COPY_ON_WRITE = 1 << 2, FILE_SEQUENTIAL = 1 << 3, FILE_TEMPORARY = 1 << 4 };