midout.h 2.2 KB
Newer Older
J
jiakai 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
#pragma once

#if defined(MIDOUT_GENERATED) || defined(MIDOUT_PROFILING)

#include <type_traits>
#include <typeinfo>

namespace midout {
    //! used as extra params to MIDOUT_BEGIN to wrap int value as type
    template<int val>
    using iv = std::integral_constant<int, val>;

//! cast compile-time constant value to int
#define midout_iv(_val) ::midout::iv<static_cast<int>(_val)>

}

/*!
 * \brief declare a tag that can be used in MIDOUT_BEGIN
 *
 * This macro must be called from the global scope
 *
 * \param tag tag name, which must be a valid C++ identifier
 */
#define MIDOUT_DECL(tag) \
namespace midout { \
namespace tags { \
    class tag; \
} \
static_assert(std::is_same<::midout::tags::tag, tags::tag>::value, \
        "MIDOUT_DECL must be called from global scope"); \
}

#endif  // MIDOUT_GENERATED || MIDOUT_PROFILING


#ifndef MIDOUT_GENERATED

#ifdef MIDOUT_PROFILING

namespace midout {
    void on_region_used(const std::type_info &type);

    template<class Tag, typename ...Args>
    struct Region {
        static void on_used() {
            on_region_used(typeid(Region));
        }
    };

}

/*!
 * \brief mark a code block to be removed if not executed during profiling
 * \param tag tag name that has been declared via MIDOUT_DECL
 *
 * Variadic args (must be classes) can be passed to disambiguate different
 * regions in the same tag
 *
 * The code block must be enclosed by a pair of braces and ended by MIDOUT_END
 */
#define MIDOUT_BEGIN(tag, ...)  \
    do { \
        ::midout::Region<::midout::tags::tag, ## __VA_ARGS__>::on_used(); \
        if (1)

#define MIDOUT_END() \
    } while(0)

#else   // MIDOUT_PROFILING

J
jiakai 已提交
72 73
#define MIDOUT_DECL(tag)
#define MIDOUT_BEGIN(tag, ...) do
J
jiakai 已提交
74 75 76 77 78 79 80 81 82 83 84 85 86 87
#define MIDOUT_END() while(0)

#endif  // MIDOUT_PROFILING

#else   // MIDOUT_GENERATED

namespace midout {
    template<class Tag, typename ...Args>
    struct Region {
        static constexpr bool enable = false;
    };

}

J
jiakai 已提交
88
MIDOUT_GENERATED
J
jiakai 已提交
89 90 91 92 93 94 95 96 97 98 99 100 101 102

#define MIDOUT_BEGIN(tag, ...)  \
    do { \
        if (::midout::Region<::midout::tags::tag, ## __VA_ARGS__>::enable)

#define MIDOUT_END() \
        else { \
            __builtin_trap(); \
        } \
    } while(0)

#endif  // MIDOUT_GENERATED

// vim: syntax=cpp.doxygen foldmethod=marker foldmarker=f{{{,f}}}