coolste Makros



  • // MSVC 2005 - spezifisch
    #define DONT_INDENT_NAMESPACE /* leer */
    
    namespace Library { DONT_INDENT_NAMESPACE
    namespace Module {
    
        void Fun();
    
    } // namespace Module
    } // namespace Library
    

    Da ich die doppelte Einrückung doof finde die MSVC 2005 hier machen würde, wenn man es "normal" schreibt.

    Sobald nach dem " { " noch etwas ausser Whitespaces oder Kommentaren kommt, rückt die Auto-Formatierung von MSVC 2005 den damit begonnenen Namespace/Scope/Block nicht mehr ein. Und das funktioniert eben auch, wenn es ein leeres Makro ist 🙂

    Bei MSVC 2012 bleibt leider nur mehr " {; " zu schreiben, oder namespace Library { namespace Module { in eine Zeile zu packen 😞



  • hustbaer schrieb:

    Bei MSVC 2012 bleibt leider nur mehr " {; " zu schreiben, oder namespace Library { namespace Module { in eine Zeile zu packen 😞

    Auch nicht

    #define DONT_INDENT_NAMESPACE ;
    

    ?



  • Swordfish schrieb:

    #define BIN_0000 0
    #define BIN_0001 1
    #define BIN_0010 2
    #define BIN_0011 3
    #define BIN_0100 4
    #define BIN_0101 5
    #define BIN_0110 6
    #define BIN_0111 7
    #define BIN_1000 8
    #define BIN_1001 9
    #define BIN_1010 a
    #define BIN_1011 b
    #define BIN_1100 c
    #define BIN_1101 d
    #define BIN_1110 e
    #define BIN_1111 f
    
    #define BIN_8_HEXIFY(b1,b2) (0x ## b1 ## b2)
    #define BIN_8_RELAY(b1,b2)  BIN_8_HEXIFY(b1,b2)
    #define BIN_8(b1,b2)        BIN_8_RELAY(BIN_ ## b1,BIN_ ## b2)
    
    #define BIN_16_HEXIFY(b1,b2,b3,b4) (0x ## b1 ## b2 ## b3 ## b4)
    #define BIN_16_RELAY(b1,b2,b3,b4)  BIN_16_HEXIFY(b1,b2,b3,b4)
    #define BIN_16(b1,b2,b3,b4)        BIN_16_RELAY(BIN_##b1,BIN_##b2,BIN_##b3,BIN_##b4)
    //...
    

    @Swordfish:
    Schlimmer gehts echt nimmer? 😉

    Dem nächsten Heinz der mir einen solchen Code abliefert darf diesen mal debuggen und ihn verifizieren. :p

    Ich sage dazu nur UAC: Ultra Albtraumhafter Code



  • volkard schrieb:

    hustbaer schrieb:

    Bei MSVC 2012 bleibt leider nur mehr " {; " zu schreiben, oder namespace Library { namespace Module { in eine Zeile zu packen 😞

    Auch nicht

    #define DONT_INDENT_NAMESPACE ;
    

    ?

    Leider auch nicht.
    Der Inhalt des #define ist ihm egal.
    Mit 2012 geht es mit dem Makro nur wenn man die "{" in die nächste Zeile setzt.

    namespace Library
    { DONT_INDENT_NAMESPACE
    namespace Module
    {
    

    Sieht finde ich komisch aus 😕
    Dann noch lieber

    namespace Library {;
    namespace Module {
    


  • Ich werf mal den Supermakro-Trick in die Runde:

    #include <iostream>
    
    namespace {
      enum color {
    #define COLOR(name) name,
    #include "colors.list"
        color_count
      };
    
      char const *const color_names[] = {
    #define COLOR(name) #name,
    #include "colors.list"
      };
    }
    
    int main() {
      std::cout << color_names[red  ] << '\n'
                << color_names[green] << '\n'
                << color_names[blue ] << '\n';
    }
    

    wobei colors.list

    COLOR(red)
    COLOR(green)
    COLOR(blue)
    
    #undef COLOR
    

    ist.



  • Hmm, nicht schlecht.



  • #define true false // happy debugging suckers



  • Da das Niveau ja immer weiter absinkt ...

    #define false '-'-'-'
    #define true  '/'/'/'
    


  • nurf schrieb:

    Da das Niveau ja immer weiter absinkt ...

    #define false '-'-'-'
    #define true  '/'/'/'
    

    das kompiliert sogar, ich staune 😮



  • Für den GCC:

    #define DO_PRAGMA(x) _Pragma(#x)
    #define TODO(x) DO_PRAGMA(message("TODO: " #x ))
    
    TODO(test); // => note: #pragma message: TODO: test
    


  • und so läufts auch auf dem MSVC.

    #define DO_PRAGMA(x) __pragma(#x)
    


  • krümelkacker schrieb:

    Ich finde das hier ganz nett:

    #define REQUIRES(...) ,class=typename std::enable_if<(__VA_ARGS__)>::type
    

    U.a. so zu verwenden in C++11:

    template<class T, class U
      REQUIRES( std::is_scalar<T>::value &&
                std::is_scalar<U>::value &&
                sizeof(T)==sizeot(U) )
    >
    inline T reinterpret_value(U x)
    {
      T y;
      std::memcpy(&y,&x,sizeof y);
      return y;
    }
    

    also für constrained templates.

    Apropos constrained templates...



  • otze schrieb:

    und so läufts auch auf dem MSVC.

    #define DO_PRAGMA(x) __pragma(#x)
    

    Waaaaaaaaaaah, MS wiedermal.
    Die Deppen.
    Weisst du ab welcher Version das geht?



  • 2 eher unspekakuläre Makros, die aber den Code bei mir echt verschönern:

    #define SYNTHETIC_CURRENT_FUNCTION &__PRETTY_FUNCTION__[0]
    #define SYNTHETIC_THROW(ErrorClass, ...) \
        throw ErrorClass(SYNTHETIC_CURRENT_FUNCTION, __VA_ARGS__)
    

    (Wobei meine Exceptionklassen alle den Funktionsnamen als ersten Konstruktorparameter nehmen)

    und

    #define REQUIRE_FILE(path, errorMsg)                    \
        do {                                                \
        if(!boost::filesystem::is_regular_file(path))       \
            SYNTHETIC_THROW(Synthetic::InvalidPathError,    \
                errorMsg, path);                            \
        } while(0)
    
    #define REQUIRE_DIRECTORY(path, errorMsg)               \
        do {                                                \
        if(!boost::filesystem::is_directory(path))          \
            SYNTHETIC_THROW(Synthetic::InvalidPathError,    \
                errorMsg, path);                            \
        } while(0)
    

    Auch recht häufig benutzt:

    #define UNUSED(x) (void)x
    


  • krümelkacker schrieb:

    krümelkacker schrieb:

    Ich finde das hier ganz nett:

    #define REQUIRES(...) ,class=typename std::enable_if<(__VA_ARGS__)>::type
    

    U.a. so zu verwenden in C++11:

    template<class T, class U
      REQUIRES( std::is_scalar<T>::value &&
                std::is_scalar<U>::value &&
                sizeof(T)==sizeot(U) )
    >
    inline T reinterpret_value(U x)
    {
      return T(reinterpret_cast<T&>(x));
    }
    

    also für constrained templates.

    Apropos constrained templates...

    Ich finde das ohne Makro etwas lesbarer

    template <bool B, class = typename std::enable_if<B>::type> struct requires;
    
    template<class T, class U,
             class=requires<std::is_trivially_copyable<T>::value &&
                            std::is_trivially_copyable<U>::value &&
                            sizeof(T)==sizeof(U)>>
    inline T reinterpret_value(U x)
    {
      T y;
      std::memcpy(&y,&x,sizeof y);
      return y;
    }
    

    oder sogar

    template <bool B, class = typename std::enable_if<B>::type> struct requires;
    template <class T, template<typename...>class C>
    constexpr bool that() { return C<T>::value; }
    
    template<class T, class U,
             class=requires<that<T, std::is_trivially_copyable>() &&
                            that<U, std::is_trivially_copyable>() &&
                            sizeof(T)==sizeof(U)>>
    inline T reinterpret_value(U x)
    {
      return T(reinterpret_cast<T&>(x));
    }
    

    (Btw, weshalb ist

    requires
    

    ein Keyword?)



  • allescalar schrieb:

    (Btw, weshalb ist

    requires
    

    ein Keyword?)

    Laut dem Link oben wird es vermutlich Keyword in C++17 . 🙂



  • Das koennen nun aber wirklich Funktionen sein, Ethon...



  • @Kellerautomat
    Ich gehe davon aus dass er es als Makro ausgeführt hat, damit er die File-/Zeilen-Info der Funktion bekommt die das Makro erweitert, anstatt immer die Info über die "RequiresFile" Funktion.

    Mit genau der selben Motivation hab' ich mir sowas gebastelt

    #define GLAZE_LOCATION_INFO() \
    	::Glaze::Log::LocationInfo( \
    		GLAZE_WIDEN(__FILE__), \
    		__LINE__, \
    		GLAZE_WIDEN(__FUNCTION__))
    
    #define GLAZE_LOCATION_INFO_N(locationName_) \
    	::Glaze::Log::LocationInfo( \
    		GLAZE_WIDEN(__FILE__), \
    		__LINE__, \
    		GLAZE_WIDEN(__FUNCTION__), \
    		(locationName_))
    

    Dann kann man eine RequiresFile Funktion machen, die einfach ein ::Glaze::Log::LocationInfo als Parameter nimmt.



  • Ah, das ergibt natuerlich Sinn.



  • Ethon schrieb:

    #define UNUSED(x) (void)x
    
    void Fun(istream& is)
    {
        UNUSED(is).get();
    }
    

    🤡
    ->

    #define UNUSED(x) ((void)x)
    

Anmelden zum Antworten