Created
November 13, 2013 20:20
-
-
Save erikerlandson/7455677 to your computer and use it in GitHub Desktop.
Demonstrate integrated support for both run-time and compile-time enabling or disabling of a feature. Note, should be compiled optimized for best results.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <boost/parameter/name.hpp> | |
#include <boost/parameter/preprocessor.hpp> | |
#include <boost/type_traits/is_arithmetic.hpp> | |
#include <boost/utility/enable_if.hpp> | |
using boost::is_same; | |
using boost::false_type; | |
using boost::true_type; | |
using boost::enable_if; | |
// default instantiation not intended to ever match | |
template <typename Count, typename Enabled=void> struct counter_impl {}; | |
// run-time enabling: checks boolean flag to see whether to count or not | |
template <typename Count> | |
struct counter_impl<Count, typename enable_if<is_same<Count, bool> >::type> { | |
bool count; | |
long long n; | |
counter_impl(const bool& count_) : count(count_), n(0) {} | |
template <typename V> inline void update(const V& v) { if (count && (v % 3 == 0)) ++n; } | |
inline long long total() const { return n; } | |
}; | |
// compile-time enabling: doesn't have to check if counting is enabled | |
template <typename Count> | |
struct counter_impl<Count, typename enable_if<is_same<Count, true_type> >::type> { | |
long long n; | |
counter_impl(const Count& count_) : n(0) {} | |
template <typename V> inline void update(const V& v) { if (v % 3 == 0) ++n; } | |
inline long long total() const { return n; } | |
}; | |
// compile-time disabling: all operations compile to nothing: | |
template <typename Count> | |
struct counter_impl<Count, typename enable_if<is_same<Count, false_type> >::type> { | |
counter_impl(const Count& count_) {} | |
template <typename V> inline void update(const V& v) const {} | |
inline long long total() const { return 0; } | |
}; | |
// implementation of demo: instantiates a counter object based on | |
// what kind of run-time or compile-time paramter was passed: | |
template <typename Count> | |
long long demo_impl(long long n, const Count& count) { | |
// this is enabled/disabled at either comile time or runtime, depending on type: | |
counter_impl<Count> counter(count); | |
for (long long j = 0; j < n; ++j) { | |
counter.update(j); | |
} | |
return counter.total(); | |
} | |
namespace parameter { | |
BOOST_PARAMETER_NAME(n) | |
BOOST_PARAMETER_NAME(count) | |
} | |
// use Boost named-parameter interface for the demo() function: | |
// 'n' is how high to count | |
// 'count' specifies either compile-time or run-time checks for counting | |
BOOST_PARAMETER_FUNCTION( | |
(long long), | |
demo, | |
parameter::tag, | |
(required (n, (long long))) | |
(optional (count, *, false_type())) | |
) | |
{ | |
return demo_impl(n, count); | |
} | |
/* | |
Expected output should look something like: | |
$ ./feature_enabling | |
true (run time) r= 3333333334 time= 11 | |
true (compile time) r= 3333333334 time= 11 | |
false (run time) r= 0 time= 6 | |
false (compile time) r= 0 time= 3 | |
*/ | |
int main(int argc, char** argv) { | |
double t0, tt; | |
long long r; | |
const long long N = 10000000000; | |
// enable counting at run time: the slowest option | |
t0 = time(0); | |
r = demo(N, parameter::_count=true); | |
tt = time(0)-t0; | |
std::cout << "true (run time) r= " << r << " time= " << tt << "\n"; | |
// enable counting at compile time: slightly faster than enabling at run-time | |
t0 = time(0); | |
r = demo(N, parameter::_count = true_type()); | |
tt = time(0)-t0; | |
std::cout << "true (compile time) r= " << r << " time= " << tt << "\n"; | |
// disable counting at run-time: significantly faster than enabled counting | |
t0 = time(0); | |
r = demo(N, parameter::_count=false); | |
tt = time(0)-t0; | |
std::cout << "false (run time) r= " << r << " time= " << tt << "\n"; | |
// disable counting at compile-time: this runs much faster than disabling at run-time | |
t0 = time(0); | |
r = demo(N, parameter::_count = false_type()); | |
tt = time(0)-t0; | |
std::cout << "false (compile time) r= " << r << " time= " << tt << "\n"; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment