Commit e2447af3 authored by LEFEBVREJP email's avatar LEFEBVREJP email
Browse files

Merge branch 'do-while' into 'master'

Macro do-while

See merge request !111
parents 4c7a6747 8c9b62e3
Pipeline #154048 passed with stages
in 17 minutes and 45 seconds
#ifndef RADIX_RADIXBUG_BUG_HH_ #ifndef RADIX_RADIXCORE_BUG_HH_
#define RADIX_RADIXBUG_BUG_HH_ #define RADIX_RADIXCORE_BUG_HH_
#ifndef DEBUG_OUTPUT
#define DEBUG_OUTPUT 0
#define DEBUG_CALL(c)
#else
#define DEBUG_CALL(c) c
#endif
// default to c++ compiler // default to c++ compiler
/* /*
...@@ -34,7 +27,7 @@ ...@@ -34,7 +27,7 @@
*/ */
#include <cstdio> #include <cstdio>
#include <iostream> #include <iostream>
#if DEBUG_OUTPUT & 1 #if RADIX_DEBUG_OUTPUT
#ifndef radix_stream #ifndef radix_stream
#define radix_stream std::cerr #define radix_stream std::cerr
#endif #endif
...@@ -79,7 +72,7 @@ ...@@ -79,7 +72,7 @@
#define radix_flush_tagged_warning(arg) #define radix_flush_tagged_warning(arg)
#define radix_tagged_block(block) #define radix_tagged_block(block)
#define radix_block(block) #define radix_block(block)
#endif /* DEBUG_OUTPUT */ #endif /* RADIX_DEBUG_OUTPUT */
#include <sstream> #include <sstream>
#include <stdexcept> #include <stdexcept>
...@@ -95,61 +88,83 @@ ...@@ -95,61 +88,83 @@
// RADIX_DBC = 7 enables all // RADIX_DBC = 7 enables all
// Insist is always enabled // Insist is always enabled
#if RADIX_DBC & 1 #if RADIX_DBC & 1
#define radix_require(c) \ #define radix_require(c) \
if (!(c)) \ do \
{ \ { \
std::ostringstream stream; \ if (!(c)) \
stream << __FILE__ << ":" << __LINE__ << " radix_require(" << #c \ { \
<< ") failed." << std::endl; \ std::ostringstream stream; \
throw std::runtime_error(stream.str()); \ stream << __FILE__ << ":" << __LINE__ << " radix_require(" << #c \
} << ") failed." << std::endl; \
throw std::runtime_error(stream.str()); \
} \
} while (false)
#else #else
#define radix_require(c) #define radix_require(c)
#endif #endif
#if RADIX_DBC & 2 #if RADIX_DBC & 2
#define radix_check(c) \ #define radix_check(c) \
if (!(c)) \ do \
{ \ { \
std::ostringstream stream; \ if (!(c)) \
stream << __FILE__ << ":" << __LINE__ << " radix_check(" << #c \ { \
<< ") failed." << std::endl; \ std::ostringstream stream; \
throw std::runtime_error(stream.str()); \ stream << __FILE__ << ":" << __LINE__ << " radix_check(" << #c \
} << ") failed." << std::endl; \
throw std::runtime_error(stream.str()); \
} \
} while (false)
#else #else
#define radix_check(c) #define radix_check(c)
#endif #endif
#if RADIX_DBC & 4 #if RADIX_DBC & 4
#define radix_ensure(c) \ #define radix_ensure(c) \
if (!(c)) \ do \
{ \ { \
std::ostringstream stream; \ if (!(c)) \
stream << __FILE__ << ":" << __LINE__ << " radix_ensure(" << #c \ { \
<< ") failed." << std::endl; \ std::ostringstream stream; \
throw std::runtime_error(stream.str()); \ stream << __FILE__ << ":" << __LINE__ << " radix_ensure(" << #c \
} << ") failed." << std::endl; \
throw std::runtime_error(stream.str()); \
} \
} while (false)
#define radix_remember(c) c #define radix_remember(c) c
#else #else
#define radix_ensure(c) #define radix_ensure(c)
#define radix_remember(c) #define radix_remember(c)
#endif #endif
#define radix_insist(c, msg) \ #define radix_insist(c, msg) \
if (!(c)) \ do \
{ \ { \
std::ostringstream stream; \ if (!(c)) \
stream << __FILE__ << ":" << __LINE__ << "radix_insist(" << #c \ { \
<< ") failed with this message:" << std::endl \ std::ostringstream stream; \
<< msg << std::endl; \ stream << __FILE__ << ":" << __LINE__ << "radix_insist(" << #c \
throw std::runtime_error(stream.str()); \ << ") failed with this message:" << std::endl \
} << msg << std::endl; \
throw std::runtime_error(stream.str()); \
} \
} while (false)
#define radix_not_implemented(msg) \ #define radix_not_implemented(msg) \
do \
{ \ { \
std::ostringstream stream; \ std::ostringstream stream; \
stream << __FILE__ << ":" << __LINE__ << " : " << msg \ stream << __FILE__ << ":" << __LINE__ << " : " << msg \
<< " is not implemented. " << std::endl; \ << " is not implemented. " << std::endl; \
throw std::runtime_error(stream.str()); \ throw std::runtime_error(stream.str()); \
} } while (false)
#define radix_not_reachable() \
do \
{ \
std::ostringstream stream; \
stream << "Execution encountered unreachable code point at " << __FILE__ \
<< ":" << __LINE__ << std::endl; \
throw std::runtime_error(stream.str()); \
} while (false)
/// set default timing to off /// set default timing to off
#ifndef RADIX_TIMING #ifndef RADIX_TIMING
...@@ -160,6 +175,11 @@ ...@@ -160,6 +175,11 @@
#include <ctime> #include <ctime>
namespace radix namespace radix
{ {
/**
* @brief Timer implementation for recording duration between start and stop
* points.
*
*/
class Timer class Timer
{ {
private: private:
...@@ -176,6 +196,10 @@ class Timer ...@@ -176,6 +196,10 @@ class Timer
, mIntervals(0) , mIntervals(0)
{ {
} }
/**
* @brief Mark the start time for this timer
*
*/
void start() void start()
{ {
radix_check(!mRunning); radix_check(!mRunning);
...@@ -183,6 +207,10 @@ class Timer ...@@ -183,6 +207,10 @@ class Timer
mIntervals++; mIntervals++;
mStart = std::chrono::steady_clock::now(); mStart = std::chrono::steady_clock::now();
} }
/**
* @brief Mark the stop time and record duration of time.
*
*/
void stop() void stop()
{ {
radix_check(mRunning); radix_check(mRunning);
...@@ -192,13 +220,30 @@ class Timer ...@@ -192,13 +220,30 @@ class Timer
std::chrono::duration_cast<std::chrono::nanoseconds>(mEnd - mStart); std::chrono::duration_cast<std::chrono::nanoseconds>(mEnd - mStart);
} }
/**
* @brief Returns duration this timer ran in nanoseconds
*
* @return std::chrono::nanoseconds::rep
*/
std::chrono::nanoseconds::rep duration() const std::chrono::nanoseconds::rep duration() const
{ {
radix_check(!mRunning); radix_check(!mRunning);
return mDuration.count(); return mDuration.count();
} }
/**
* @brief Returns the number times this timer was started and subsequently
* stopped.
*
* @return size_t
*/
size_t intervals() const { return mIntervals; } size_t intervals() const { return mIntervals; }
/**
* @brief Returns the duration this timer ran in wall clock seconds.
* Does not account for intervals
* @return double durantion in seconds
*/
double wall_clock() double wall_clock()
{ {
radix_require(!mRunning); radix_require(!mRunning);
...@@ -207,6 +252,12 @@ class Timer ...@@ -207,6 +252,12 @@ class Timer
return seconds(mEnd - mStart).count(); return seconds(mEnd - mStart).count();
} }
/**
* @brief Returns the duration this timer ran accounting for start/stop
* intervals
*
* @return double duration in seconds
*/
double sum_wall_clock() double sum_wall_clock()
{ {
// 1e9 nanoseconds in a second // 1e9 nanoseconds in a second
...@@ -214,6 +265,12 @@ class Timer ...@@ -214,6 +265,12 @@ class Timer
return seconds(mDuration).count(); return seconds(mDuration).count();
} }
/**
* @brief Returns whether this timer is currently counting.
*
* @return true The timer is running.
* @return false The timer is not running.
*/
bool running() const { return mRunning; }; bool running() const { return mRunning; };
}; };
...@@ -255,4 +312,4 @@ class Timer ...@@ -255,4 +312,4 @@ class Timer
#define radix_timer_block_3(content) #define radix_timer_block_3(content)
#endif #endif
#endif /* RADIX_RADIXBUG_BUG_HH_*/ #endif /* RADIX_RADIXCORE_BUG_HH_*/
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// force RADIX_TIMING on // force RADIX_TIMING on
#define RADIX_TIMING 3 #define RADIX_TIMING 3
// force RADIX_DBC on
#define RADIX_DBC 7
#include "radixbug/bug.hh" #include "radixbug/bug.hh"
TEST(radixbug, Timer) TEST(radixbug, Timer)
...@@ -47,3 +49,66 @@ TEST(radixbug, Timer) ...@@ -47,3 +49,66 @@ TEST(radixbug, Timer)
std::cout << "Wall clock (s): " << timer1.wall_clock() << std::endl; std::cout << "Wall clock (s): " << timer1.wall_clock() << std::endl;
std::cout << "Sum wall clock (s): " << timer1.sum_wall_clock() << std::endl; std::cout << "Sum wall clock (s): " << timer1.sum_wall_clock() << std::endl;
} }
TEST(radixcore, DBC)
{
try
{
radix_check(false);
EXPECT_TRUE(false);
}
catch (const std::runtime_error& e)
{
std::cout << "Successful radix_check()" << std::endl;
radix_check(true);
}
try
{
radix_require(false);
EXPECT_TRUE(false);
}
catch (const std::runtime_error& e)
{
std::cout << "Successful radix_require()" << std::endl;
radix_require(true);
}
try
{
radix_ensure(false);
EXPECT_TRUE(false);
}
catch (const std::runtime_error& e)
{
std::cout << "Successful radix_ensure()" << std::endl;
radix_ensure(true);
}
try
{
radix_insist(false, "Will cause error");
EXPECT_TRUE(false);
}
catch (const std::runtime_error& e)
{
std::cout << "Successful radix_insist()" << std::endl;
radix_insist(true, "Will not cause error");
}
try
{
radix_not_implemented("not implemented");
EXPECT_TRUE(false);
}
catch (const std::runtime_error& e)
{
std::cout << "Successful radix_not_implemented()" << std::endl;
}
try
{
radix_not_reachable();
EXPECT_TRUE(false);
}
catch (const std::runtime_error& e)
{
std::cout << "Successful radix_not_reachable()" << std::endl;
}
}
...@@ -276,9 +276,9 @@ int Value::to_int() const ...@@ -276,9 +276,9 @@ int Value::to_int() const
radix_not_implemented("conversion of array to integer"); radix_not_implemented("conversion of array to integer");
case TYPE_OBJECT: case TYPE_OBJECT:
radix_not_implemented("conversion of object to integer") radix_not_implemented("conversion of object to integer");
} }
radix_not_implemented("unknown type conversion to integer") radix_not_implemented("unknown type conversion to integer");
} }
double Value::to_double() const double Value::to_double() const
{ {
...@@ -305,9 +305,9 @@ double Value::to_double() const ...@@ -305,9 +305,9 @@ double Value::to_double() const
radix_not_implemented("conversion of array to double"); radix_not_implemented("conversion of array to double");
case TYPE_OBJECT: case TYPE_OBJECT:
radix_not_implemented("conversion of object to double") radix_not_implemented("conversion of object to double");
} }
radix_not_implemented("unknown type conversion to double") radix_not_implemented("unknown type conversion to double");
} }
bool Value::to_bool() const bool Value::to_bool() const
{ {
...@@ -332,9 +332,9 @@ bool Value::to_bool() const ...@@ -332,9 +332,9 @@ bool Value::to_bool() const
radix_not_implemented("conversion of array to double"); radix_not_implemented("conversion of array to double");
case TYPE_OBJECT: case TYPE_OBJECT:
radix_not_implemented("conversion of object to double") radix_not_implemented("conversion of object to double");
} }
radix_not_implemented("unknown type conversion to bool") radix_not_implemented("unknown type conversion to bool");
} }
const char* Value::to_cstring() const const char* Value::to_cstring() const
{ {
...@@ -353,9 +353,9 @@ const char* Value::to_cstring() const ...@@ -353,9 +353,9 @@ const char* Value::to_cstring() const
radix_not_implemented("conversion of array to cstring"); radix_not_implemented("conversion of array to cstring");
case TYPE_OBJECT: case TYPE_OBJECT:
radix_not_implemented("conversion of object to cstring") radix_not_implemented("conversion of object to cstring");
} }
radix_not_implemented("unknown type conversion to cstring") radix_not_implemented("unknown type conversion to cstring");
} }
std::string Value::to_string() const std::string Value::to_string() const
{ {
...@@ -381,50 +381,48 @@ std::string Value::to_string() const ...@@ -381,50 +381,48 @@ std::string Value::to_string() const
to_object()->pack_json(str); to_object()->pack_json(str);
return str.str(); return str.str();
} }
radix_not_implemented("unknown type conversion to string") radix_not_implemented("unknown type conversion to string");
} }
DataArray* Value::to_array() const DataArray* Value::to_array() const
{ {
radix_insist( radix_insist(convertable(TYPE_ARRAY),
convertable(TYPE_ARRAY), "Value object must be convertable to an array");
"Value object must be convertable to an array") return m_data.m_array; return m_data.m_array;
} }
DataObject* Value::to_object() const DataObject* Value::to_object() const
{ {
radix_insist( radix_insist(convertable(TYPE_OBJECT),
convertable(TYPE_OBJECT), "Value object must be convertable to an object");
"Value object must be convertable to an object") return m_data.m_object; return m_data.m_object;
} }
const DataArray& Value::as_array() const const DataArray& Value::as_array() const
{ {
radix_insist( radix_insist(convertable(TYPE_ARRAY),
convertable(TYPE_ARRAY), "Value object must be convertable to an array");
"Value object must be convertable to an array") return *(m_data.m_array); return *(m_data.m_array);
} }
DataArray& Value::as_array() DataArray& Value::as_array()
{ {
radix_insist( radix_insist(convertable(TYPE_ARRAY),
convertable(TYPE_ARRAY), "Value object must be convertable to an array");
"Value object must be convertable to an array") return *(m_data.m_array); return *(m_data.m_array);
} }
const DataObject& Value::as_object() const const DataObject& Value::as_object() const
{ {
radix_insist( radix_insist(convertable(TYPE_OBJECT),
convertable(TYPE_OBJECT), "Value object must be convertable to an object");
"Value object must be convertable to an object") return *(m_data return *(m_data.m_object);
.m_object);
} }
DataObject& Value::as_object() DataObject& Value::as_object()
{ {
radix_insist( radix_insist(convertable(TYPE_OBJECT),
convertable(TYPE_OBJECT), "Value object must be convertable to an object");
"Value object must be convertable to an object") return *(m_data return *(m_data.m_object);
.m_object);
} }
bool Value::convertable(Value::Type to) const bool Value::convertable(Value::Type to) const
{ {
...@@ -443,7 +441,7 @@ bool Value::convertable(Value::Type to) const ...@@ -443,7 +441,7 @@ bool Value::convertable(Value::Type to) const
case TYPE_OBJECT: case TYPE_OBJECT:
return is_object(); return is_object();
} }
radix_not_implemented("unknown type conversion") radix_not_implemented("unknown type conversion");
} }
Value& Value::operator[](const std::string& name) Value& Value::operator[](const std::string& name)
...@@ -531,7 +529,7 @@ bool Value::format_json(std::ostream& out, int indent_level, int level, ...@@ -531,7 +529,7 @@ bool Value::format_json(std::ostream& out, int indent_level, int level,
out << "null"; out << "null";
break; break;
default: default:
radix_not_implemented("unknown Object value type json emission") radix_not_implemented("unknown Object value type json emission");
} }
} }
return out.good(); return out.good();
...@@ -567,7 +565,7 @@ bool Value::pack_json(std::ostream& out) const ...@@ -567,7 +565,7 @@ bool Value::pack_json(std::ostream& out) const
out << "null"; out << "null";
break; break;
default: default:
radix_not_implemented("unknown Object value type json emission") radix_not_implemented("unknown Object value type json emission");
} }
} }
return out.good(); return out.good();
...@@ -678,8 +676,8 @@ void DataArray::merge(const DataArray& rhs) ...@@ -678,8 +676,8 @@ void DataArray::merge(const DataArray& rhs)
} }
DataObject::DataObject() {} DataObject::DataObject() {}
DataObject::DataObject(const DataObject& orig) DataObject::DataObject(const DataObject& orig)
: m_data(orig.m_data) : m_insert_order(orig.m_insert_order)
, m_insert_order(orig.m_insert_order) , m_data(orig.m_data)
{ {
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment