context.Result(ret)
return ret
+# Test for the presence of C++11 static asserts. If the compiler lacks
+# support for static asserts, base/compiler.hh enables a macro that
+# removes any static asserts in the code.
+def CheckStaticAssert(context):
+ context.Message("Checking for C++11 static_assert support...")
+ ret = context.TryCompile('''
+ static_assert(1, "This assert is always true");
+ ''', extension=".cc")
+ context.env.Append(HAVE_STATIC_ASSERT=ret)
+ context.Result(ret)
+ return ret
+
# Platform-specific configuration. Note again that we assume that all
# builds under a given build root run on the same host platform.
conf = Configure(main,
conf_dir = joinpath(build_root, '.scons_config'),
log_file = joinpath(build_root, 'scons_config.log'),
- custom_tests = { 'CheckLeading' : CheckLeading })
+ custom_tests = { 'CheckLeading' : CheckLeading,
+ 'CheckStaticAssert' : CheckStaticAssert,
+ })
# Check for leading underscores. Don't really need to worry either
# way so don't need to check the return code.
conf.CheckLeading()
+# Check for C++11 features we want to use if they exist
+conf.CheckStaticAssert()
+
# Check if we should compile a 64 bit binary on Mac OS X/Darwin
try:
import platform
# These variables get exported to #defines in config/*.hh (see src/SConscript).
export_vars += ['USE_FENV', 'SS_COMPATIBLE_FP',
'TARGET_ISA', 'CP_ANNOTATE', 'USE_POSIX_CLOCK', 'PROTOCOL',
- ]
+ 'HAVE_STATIC_ASSERT']
###################################################
#
#ifndef __BASE_COMPILER_HH__
#define __BASE_COMPILER_HH__
+#include "config/have_static_assert.hh"
+
//http://msdn2.microsoft.com/en-us/library/ms937669.aspx
//http://msdn2.microsoft.com/en-us/library/aa448724.aspx
//http://docs.sun.com/source/819-3688/sun.specific.html#marker-998278
#error "Need to define compiler options in base/compiler.hh"
#endif
+/*
+ * Define a compatibility macro that emulates the behavior of
+ * static_assert using template magic if the compiler doesn't have
+ * native support.
+ */
+#if !HAVE_STATIC_ASSERT
+
+template<bool>
+struct static_assert_failure;
+
+template<>
+struct static_assert_failure<false> {};
+
+/* The following macro causes the compiler to evaluate the size of the
+ * static_assert_failure struct. The templates are designed so that
+ * only static_assert_failure<false> evaluates to a proper size, while
+ * static_assert_failure<true> generates a compile time error.
+ */
+#define static_assert(expr, msg) \
+ namespace ns_static_assert { \
+ enum { \
+ static_assert_ ## __LINE__ = \
+ sizeof(static_assert_failure<!(expr)>) \
+ }; \
+ }
+
+#endif
+
#endif // __BASE_COMPILER_HH__