forked from catchorg/Catch2
		
	Changes done to Nonius: * Moved things into "Catch::Benchmark" namespace * Benchmarks were integrated with `TEST_CASE`/`SECTION`/`GENERATE` macros * Removed Nonius's parameters for benchmarks, Generators should be used instead * Added relevant methods to the reporter interface (default-implemented, to avoid breaking existing 3rd party reporters) * Async processing is guarded with `_REENTRANT` macro for GCC/Clang, used by default on MSVC * Added a macro `CATCH_CONFIG_DISABLE_BENCHMARKING` that removes all traces of benchmarking from Catch
		
			
				
	
	
		
			69 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			69 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*
 | 
						|
 *  Created by Joachim on 16/04/2019.
 | 
						|
 *  Adapted from donated nonius code.
 | 
						|
 *
 | 
						|
 *  Distributed under the Boost Software License, Version 1.0. (See accompanying
 | 
						|
 *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 | 
						|
 */
 | 
						|
 | 
						|
 // Hinting the optimizer
 | 
						|
 | 
						|
#ifndef TWOBLUECUBES_CATCH_OPTIMIZER_HPP_INCLUDED
 | 
						|
#define TWOBLUECUBES_CATCH_OPTIMIZER_HPP_INCLUDED
 | 
						|
 | 
						|
#if defined(_MSC_VER)
 | 
						|
#   include <atomic> // atomic_thread_fence
 | 
						|
#endif
 | 
						|
 | 
						|
namespace Catch {
 | 
						|
    namespace Benchmark {
 | 
						|
#if defined(__GNUC__) || defined(__clang__)
 | 
						|
        template <typename T>
 | 
						|
        inline void keep_memory(T* p) {
 | 
						|
            asm volatile("" : : "g"(p) : "memory");
 | 
						|
        }
 | 
						|
        inline void keep_memory() {
 | 
						|
            asm volatile("" : : : "memory");
 | 
						|
        }
 | 
						|
 | 
						|
        namespace Detail {
 | 
						|
            inline void optimizer_barrier() { keep_memory(); }
 | 
						|
        } // namespace Detail
 | 
						|
#elif defined(_MSC_VER)
 | 
						|
 | 
						|
#pragma optimize("", off)
 | 
						|
        template <typename T>
 | 
						|
        inline void keep_memory(T* p) {
 | 
						|
            // thanks @milleniumbug
 | 
						|
            *reinterpret_cast<char volatile*>(p) = *reinterpret_cast<char const volatile*>(p);
 | 
						|
        }
 | 
						|
        // TODO equivalent keep_memory()
 | 
						|
#pragma optimize("", on)
 | 
						|
 | 
						|
        namespace Detail {
 | 
						|
            inline void optimizer_barrier() {
 | 
						|
                std::atomic_thread_fence(std::memory_order_seq_cst);
 | 
						|
            }
 | 
						|
        } // namespace Detail
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
        template <typename T>
 | 
						|
        inline void deoptimize_value(T&& x) {
 | 
						|
            keep_memory(&x);
 | 
						|
        }
 | 
						|
 | 
						|
        template <typename Fn, typename... Args>
 | 
						|
        inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<!std::is_same<void, decltype(fn(args...))>::value>::type {
 | 
						|
            deoptimize_value(std::forward<Fn>(fn) (std::forward<Args...>(args...)));
 | 
						|
        }
 | 
						|
 | 
						|
        template <typename Fn, typename... Args>
 | 
						|
        inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<std::is_same<void, decltype(fn(args...))>::value>::type {
 | 
						|
            std::forward<Fn>(fn) (std::forward<Args...>(args...));
 | 
						|
        }
 | 
						|
    } // namespace Benchmark
 | 
						|
} // namespace Catch
 | 
						|
 | 
						|
#endif // TWOBLUECUBES_CATCH_OPTIMIZER_HPP_INCLUDED
 |