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 
    };
    

Anmelden zum Antworten