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 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
#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;
    };

}

#include MIDOUT_GENERATED

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