format: reimplement format rendering
requires literal string arrays, and implements more of the specifier specification. does not implement 'n' or '$' specifiers. falls back to snprintf for real arguments.
This commit is contained in:
parent
f9fb0873d3
commit
8cc4c1e82a
@ -286,8 +286,9 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
constexpr void panic [[noreturn]] (const char*);
|
constexpr void panic [[noreturn]] (const char*);
|
||||||
|
|
||||||
template <typename ...Args>
|
template <typename ...Args, size_t N>
|
||||||
constexpr void panic [[noreturn]] (const char *fmt, const Args&...);
|
constexpr
|
||||||
|
void panic [[noreturn]] (const char (&fmt)[N], const Args&...);
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
14
debug.ipp
14
debug.ipp
@ -28,9 +28,13 @@
|
|||||||
namespace util { namespace debug { namespace detail {
|
namespace util { namespace debug { namespace detail {
|
||||||
void panic [[noreturn]] (const char *msg);
|
void panic [[noreturn]] (const char *msg);
|
||||||
|
|
||||||
template <typename ...Args>
|
template <typename ...Args, size_t N>
|
||||||
void panic [[noreturn]] (const char *msg, const Args& ...args)
|
constexpr
|
||||||
{ panic (util::format::render (msg, args...).c_str ()); }
|
void panic [[noreturn]] (const char (&fmt)[N], const Args& ...args)
|
||||||
|
{
|
||||||
|
auto msg = util::format::render (fmt, args...);
|
||||||
|
panic (msg.c_str ());
|
||||||
|
}
|
||||||
|
|
||||||
void not_implemented [[noreturn]] (const char *msg);
|
void not_implemented [[noreturn]] (const char *msg);
|
||||||
void unreachable [[noreturn]] (const char *msg);
|
void unreachable [[noreturn]] (const char *msg);
|
||||||
@ -92,10 +96,10 @@ constexpr void panic [[noreturn]] (const char *msg)
|
|||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
template <typename ...Args>
|
template <typename ...Args, size_t N>
|
||||||
constexpr
|
constexpr
|
||||||
void
|
void
|
||||||
panic [[noreturn]] (const char *fmt, const Args& ...args)
|
panic [[noreturn]] (const char (&fmt)[N], const Args& ...args)
|
||||||
{
|
{
|
||||||
! fmt
|
! fmt
|
||||||
? panic ("unreachable constexpr panic helper")
|
? panic ("unreachable constexpr panic helper")
|
||||||
|
56
format.cpp
56
format.cpp
@ -17,3 +17,59 @@
|
|||||||
#include "format.hpp"
|
#include "format.hpp"
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
|
||||||
|
namespace util { namespace format { namespace detail {
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
std::ostream&
|
||||||
|
operator<< (std::ostream &os, specifier::repr r)
|
||||||
|
{
|
||||||
|
switch (r) {
|
||||||
|
case specifier::repr::FIXED: return os << "FIXED";
|
||||||
|
case specifier::repr::SCIENTIFIC: return os << "SCIENTIFIC";
|
||||||
|
case specifier::repr::AUTO: return os << "AUTO";
|
||||||
|
}
|
||||||
|
|
||||||
|
unreachable ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
std::ostream&
|
||||||
|
operator<< (std::ostream &os, specifier::kind t)
|
||||||
|
{
|
||||||
|
switch (t) {
|
||||||
|
case specifier::kind::UNSIGNED: return os << "UNSIGNED";
|
||||||
|
case specifier::kind::SIGNED: return os << "SIGNED";
|
||||||
|
case specifier::kind::REAL: return os << "REAL";
|
||||||
|
case specifier::kind::STRING: return os << "STRING";
|
||||||
|
case specifier::kind::POINTER: return os << "POINTER";
|
||||||
|
case specifier::kind::CHARACTER: return os << "CHARACTER";
|
||||||
|
case specifier::kind::ESCAPE: return os << "ESCAPE";
|
||||||
|
case specifier::kind::OSTREAM: return os << "OSTREAM";
|
||||||
|
}
|
||||||
|
|
||||||
|
unreachable ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
std::ostream&
|
||||||
|
operator<< (std::ostream &os, const specifier &s)
|
||||||
|
{
|
||||||
|
return os << "specifier {"
|
||||||
|
"alternate_form: " << s.alternate_form << ", "
|
||||||
|
"left_adjusted: " << s.left_adjusted << ", "
|
||||||
|
"thousands_grouping: " << s.thousands_grouping << ", "
|
||||||
|
"padding_char: '" << s.padding_char << "', "
|
||||||
|
"positive_char: '" << s.positive_char << "', "
|
||||||
|
"uppercase: " << s.uppercase << ", "
|
||||||
|
"base: " << s.base << ", "
|
||||||
|
"repr: " << s.r << ", "
|
||||||
|
"kind: " << s.k << ", "
|
||||||
|
"width: " << s.width << ", "
|
||||||
|
"precision: " << s.precision << ", "
|
||||||
|
"length: " << s.length <<
|
||||||
|
" }";
|
||||||
|
}
|
||||||
|
} } }
|
||||||
|
71
format.hpp
71
format.hpp
@ -11,7 +11,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
* Copyright 2015-2016 Danny Robson <danny@nerdcruft.net>
|
* Copyright 2016 Danny Robson <danny@nerdcruft.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __UTIL_FORMAT_HPP
|
#ifndef __UTIL_FORMAT_HPP
|
||||||
@ -20,41 +20,56 @@
|
|||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace util {
|
namespace util { namespace format {
|
||||||
namespace format {
|
//-------------------------------------------------------------------------
|
||||||
template <typename ...Args>
|
// render a format string using the provided values.
|
||||||
std::string
|
//
|
||||||
render (const std::string &fmt, Args&&...);
|
// we deliberately only take char[] formats so as to promote the use of
|
||||||
|
// only literal strings as format strings.
|
||||||
|
template <typename ...Args, size_t N>
|
||||||
|
std::string
|
||||||
|
render (const char (&fmt)[N], const Args&...);
|
||||||
|
|
||||||
class error : public std::runtime_error
|
//-------------------------------------------------------------------------
|
||||||
{ using runtime_error::runtime_error; };
|
class error : public std::runtime_error
|
||||||
|
{ using runtime_error::runtime_error; };
|
||||||
|
|
||||||
// value-specifier mismatch
|
// value-specifier mismatch
|
||||||
class value_error : public error
|
class value_error : public error
|
||||||
{ using error::error; };
|
{ using error::error; };
|
||||||
|
|
||||||
// malformed format specifier
|
struct conversion_error : public error
|
||||||
class format_error : public error
|
{ using error::error; };
|
||||||
{ using error::error; };
|
|
||||||
|
|
||||||
template <typename ValueT>
|
struct length_error : public error
|
||||||
class invalid_specifier : public format_error {
|
{ using error::error; };
|
||||||
public:
|
|
||||||
using value_type = ValueT;
|
|
||||||
|
|
||||||
invalid_specifier (char specifier);
|
// malformed format specifier
|
||||||
|
class syntax_error : public error
|
||||||
|
{ using error::error; };
|
||||||
|
|
||||||
char specifier (void) const;
|
template <typename ValueT>
|
||||||
|
class invalid_specifier : error {
|
||||||
|
public:
|
||||||
|
using value_type = ValueT;
|
||||||
|
|
||||||
private:
|
invalid_specifier (char specifier);
|
||||||
char m_specifier;
|
|
||||||
};
|
|
||||||
|
|
||||||
// missing format specifier
|
char specifier (void) const;
|
||||||
class missing_error : public error
|
|
||||||
{ using error::error; };
|
private:
|
||||||
}
|
char m_specifier;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
// missing format specifier
|
||||||
|
class missing_error : public error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
missing_error ():
|
||||||
|
error ("missing argument for specifier")
|
||||||
|
{ ; }
|
||||||
|
};
|
||||||
|
} }
|
||||||
|
|
||||||
#include "format.ipp"
|
#include "format.ipp"
|
||||||
|
|
||||||
|
1067
format.ipp
1067
format.ipp
File diff suppressed because it is too large
Load Diff
4
log.hpp
4
log.hpp
@ -61,8 +61,8 @@ namespace util {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
void log (level_t, const std::string &msg);
|
void log (level_t, const std::string &msg);
|
||||||
|
|
||||||
template <typename ...tail>
|
template <typename ...Args, size_t N>
|
||||||
void log (level_t, const std::string &format, tail&& ..._tail);
|
void log (level_t, const char (&fmt)[N], const Args&...);
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
6
log.ipp
6
log.ipp
@ -24,11 +24,11 @@
|
|||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
namespace util {
|
namespace util {
|
||||||
template <typename ...tail>
|
template <typename ...Args, size_t N>
|
||||||
void
|
void
|
||||||
log (level_t l, const std::string &format, tail&& ..._tail)
|
log (level_t l, const char (&fmt)[N], const Args& ...args)
|
||||||
{
|
{
|
||||||
log (l, format::render (format, std::forward<tail> (_tail)...));
|
log (l, format::render (fmt, args...));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
20
maths.cpp
20
maths.cpp
@ -57,26 +57,6 @@ template uint32_t util::log2 (uint32_t);
|
|||||||
template uint64_t util::log2 (uint64_t);
|
template uint64_t util::log2 (uint64_t);
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace util {
|
|
||||||
template <>
|
|
||||||
unsigned
|
|
||||||
digits (const uint32_t &v)
|
|
||||||
{
|
|
||||||
return (v >= 1000000000) ? 10 :
|
|
||||||
(v >= 100000000) ? 9 :
|
|
||||||
(v >= 10000000) ? 8 :
|
|
||||||
(v >= 1000000) ? 7 :
|
|
||||||
(v >= 100000) ? 6 :
|
|
||||||
(v >= 10000) ? 5 :
|
|
||||||
(v >= 1000) ? 4 :
|
|
||||||
(v >= 100) ? 3 :
|
|
||||||
(v >= 10) ? 2 :
|
|
||||||
1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::enable_if_t<
|
std::enable_if_t<
|
||||||
|
49
maths.hpp
49
maths.hpp
@ -17,10 +17,14 @@
|
|||||||
#ifndef __MATHS_HPP
|
#ifndef __MATHS_HPP
|
||||||
#define __MATHS_HPP
|
#define __MATHS_HPP
|
||||||
|
|
||||||
#include "./debug.hpp"
|
// DO NOT INCLUDE debug.hpp
|
||||||
|
// it triggers a circular dependency; debug -> format -> maths -> debug
|
||||||
|
// instead, just use cassert
|
||||||
|
|
||||||
#include "./types/traits.hpp"
|
#include "./types/traits.hpp"
|
||||||
#include "./float.hpp"
|
#include "./float.hpp"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
@ -281,9 +285,40 @@ namespace util {
|
|||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
template <typename T>
|
constexpr
|
||||||
unsigned
|
unsigned
|
||||||
digits (const T& value);
|
digits10 (uint32_t v) noexcept
|
||||||
|
{
|
||||||
|
return (v >= 1000000000) ? 10 :
|
||||||
|
(v >= 100000000) ? 9 :
|
||||||
|
(v >= 10000000) ? 8 :
|
||||||
|
(v >= 1000000) ? 7 :
|
||||||
|
(v >= 100000) ? 6 :
|
||||||
|
(v >= 10000) ? 5 :
|
||||||
|
(v >= 1000) ? 4 :
|
||||||
|
(v >= 100) ? 3 :
|
||||||
|
(v >= 10) ? 2 :
|
||||||
|
1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename ValueT, typename BaseT>
|
||||||
|
constexpr
|
||||||
|
std::enable_if_t<
|
||||||
|
std::is_integral<ValueT>::value && std::is_unsigned<BaseT>::value,
|
||||||
|
unsigned
|
||||||
|
>
|
||||||
|
digits (ValueT value, BaseT base) noexcept
|
||||||
|
{
|
||||||
|
if (value < 0)
|
||||||
|
return digits (-value, base);
|
||||||
|
|
||||||
|
unsigned tally = 1;
|
||||||
|
while (value /= base)
|
||||||
|
++tally;
|
||||||
|
|
||||||
|
return tally;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///----------------------------------------------------------------------------
|
///----------------------------------------------------------------------------
|
||||||
@ -326,8 +361,8 @@ namespace util {
|
|||||||
constexpr T
|
constexpr T
|
||||||
gcd (T a, T b)
|
gcd (T a, T b)
|
||||||
{
|
{
|
||||||
CHECK_NEZ (a);
|
assert (a);
|
||||||
CHECK_NEZ (b);
|
assert (b);
|
||||||
|
|
||||||
while (a != b) {
|
while (a != b) {
|
||||||
if (a > b)
|
if (a > b)
|
||||||
@ -506,7 +541,7 @@ namespace util {
|
|||||||
constexpr T
|
constexpr T
|
||||||
limit (const T val, const U lo, const V hi)
|
limit (const T val, const U lo, const V hi)
|
||||||
{
|
{
|
||||||
CHECK_LE (lo, hi);
|
assert (lo <= hi);
|
||||||
|
|
||||||
return val > hi ? hi:
|
return val > hi ? hi:
|
||||||
val < lo ? lo:
|
val < lo ? lo:
|
||||||
@ -520,7 +555,7 @@ namespace util {
|
|||||||
T
|
T
|
||||||
smoothstep (T a, T b, T x)
|
smoothstep (T a, T b, T x)
|
||||||
{
|
{
|
||||||
CHECK_LE(a, b);
|
assert (a <= b);
|
||||||
x = limit ((x - a) / (b - a), T{0}, T{1});
|
x = limit ((x - a) / (b - a), T{0}, T{1});
|
||||||
return x * x * (3 - 2 * x);
|
return x * x * (3 - 2 * x);
|
||||||
}
|
}
|
||||||
|
44
tap.hpp
44
tap.hpp
@ -37,42 +37,42 @@ namespace util { namespace TAP {
|
|||||||
~logger ();
|
~logger ();
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
template <typename ...Args>
|
template <typename ...Args, size_t N>
|
||||||
void expect (bool, const std::string &fmt, Args&&...);
|
void expect (bool, const char (&fmt)[N], Args&&...);
|
||||||
|
|
||||||
template <typename ...Args>
|
template <typename ...Args, size_t N>
|
||||||
void expect (const std::function<bool(Args...)>&, Args&&..., const std::string& msg);
|
void expect (const std::function<bool(Args...)>&, Args&&..., const char (&msg)[N]);
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
template <typename T, typename U, typename ...Args>
|
template <typename T, typename U, typename ...Args, size_t N>
|
||||||
void expect_eq (const T&, const U&, const std::string &fmt, Args&&...);
|
void expect_eq (const T&, const U&, const char (&fmt)[N], Args&&...);
|
||||||
|
|
||||||
template <typename T, typename U, typename ...Args>
|
template <typename T, typename U, typename ...Args, size_t N>
|
||||||
void expect_neq (const T&, const U&, const std::string &fmt, Args&&...);
|
void expect_neq (const T&, const U&, const char (&fmt)[N], Args&&...);
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
template <typename T, typename U, typename ...Args>
|
template <typename T, typename U, typename ...Args, size_t N>
|
||||||
void expect_gt (const T&, const U&, const std::string &fmt, Args&&...);
|
void expect_gt (const T&, const U&, const char (&fmt)[N], Args&&...);
|
||||||
|
|
||||||
template <typename T, typename U, typename ...Args>
|
template <typename T, typename U, typename ...Args, size_t N>
|
||||||
void expect_ge (const T&, const U&, const std::string &fmt, Args&&...);
|
void expect_ge (const T&, const U&, const char (&fmt)[N], Args&&...);
|
||||||
|
|
||||||
template <typename T, typename U, typename ...Args>
|
template <typename T, typename U, typename ...Args, size_t N>
|
||||||
void expect_lt (const T&, const U&, const std::string &fmt, Args&&...);
|
void expect_lt (const T&, const U&, const char (&fmt)[N], Args&&...);
|
||||||
|
|
||||||
template <typename T, typename U, typename ...Args>
|
template <typename T, typename U, typename ...Args, size_t N>
|
||||||
void expect_le (const T&, const U&, const std::string &fmt, Args&&...);
|
void expect_le (const T&, const U&, const char (&fmt)[N], Args&&...);
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
template <typename T, typename ...Args>
|
template <typename T, typename ...Args, size_t N>
|
||||||
void expect_nan (const T&, const std::string &fmt, Args&&...);
|
void expect_nan (const T&, const char (&fmt)[N], Args&&...);
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
template <typename T, typename ...Args>
|
template <typename T, typename ...Args, size_t N>
|
||||||
void expect_nothrow (T&&, const std::string &fmt, Args&&...);
|
void expect_nothrow (T&&, const char (&fmt)[N], Args&&...);
|
||||||
|
|
||||||
template <typename E, typename T, typename ...Args>
|
template <typename E, typename T, typename ...Args, size_t N>
|
||||||
void expect_throw (T&&, const std::string &fmt, Args&&...);
|
void expect_throw (T&&, const char (&fmt)[N], Args&&...);
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
void skip (const std::string &msg);
|
void skip (const std::string &msg);
|
||||||
|
84
tap.ipp
84
tap.ipp
@ -29,9 +29,9 @@
|
|||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
template <typename ...Args>
|
template <typename ...Args, size_t N>
|
||||||
void
|
void
|
||||||
util::TAP::logger::expect (bool test, const std::string &fmt, Args&&... args)
|
util::TAP::logger::expect (bool test, const char (&fmt)[N], Args&&... args)
|
||||||
{
|
{
|
||||||
std::cout << (test ? "ok " : "not ok ") << ++m_size
|
std::cout << (test ? "ok " : "not ok ") << ++m_size
|
||||||
<< " - "
|
<< " - "
|
||||||
@ -43,61 +43,42 @@ util::TAP::logger::expect (bool test, const std::string &fmt, Args&&... args)
|
|||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
template <typename... Args>
|
template <typename ...Args, size_t N>
|
||||||
void
|
void
|
||||||
util::TAP::logger::expect (const std::function<bool(Args...)> &test, Args&&... args, const std::string &msg)
|
util::TAP::logger::expect (const std::function<bool(Args...)> &test, Args&&... args, const char (&fmt)[N])
|
||||||
{
|
{
|
||||||
expect (test (std::forward<Args> (args)...), msg);
|
expect (test (std::forward<Args> (args)...), fmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename T, typename U, typename ...Args, size_t N>
|
||||||
|
void
|
||||||
|
util::TAP::logger::expect_eq (const T&a, const U &b, const char (&fmt)[N], Args&&... args)
|
||||||
|
{
|
||||||
|
expect (almost_equal (a, b), fmt, std::forward<Args> (args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
template <typename T, typename U, typename ...Args>
|
template <typename T, typename U, typename ...Args, size_t N>
|
||||||
void
|
void
|
||||||
util::TAP::logger::expect_eq (const T&a, const U &b, const std::string &fmt, Args&&... args)
|
util::TAP::logger::expect_neq (const T&a, const U &b, const char (&fmt)[N], Args&&... args)
|
||||||
{
|
{
|
||||||
static const std::function<bool(const T&,const U&)> TEST = [] (const T &t, const U &u) -> bool {
|
expect (!almost_equal (a, b), fmt, std::forward<Args> (args)...);
|
||||||
return almost_equal (t, u);
|
|
||||||
};
|
|
||||||
|
|
||||||
expect<const T&, const U&> (TEST, a, b, util::format::render (fmt, std::forward<Args> (args)...));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
template <typename T, typename U, typename ...Args>
|
|
||||||
void
|
|
||||||
util::TAP::logger::expect_neq (const T&a, const U &b, const std::string &fmt, Args&&... args)
|
|
||||||
{
|
|
||||||
static const std::function<bool(const T&,const U&)> TEST = [] (const T &t, const U &u) -> bool {
|
|
||||||
return !almost_equal (t, u);
|
|
||||||
};
|
|
||||||
|
|
||||||
expect<const T&, const U&> (TEST, a, b, util::format::render (fmt, std::forward<Args> (args)...));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
#define TAP_TEST(SUFFIX,OP) \
|
#define TAP_TEST(SUFFIX,OP) \
|
||||||
template <typename T, typename U, typename ...Args> \
|
template <typename T, typename U, typename ...Args, size_t N> \
|
||||||
void \
|
void \
|
||||||
util::TAP::logger::expect_ ## SUFFIX (const T &a, \
|
util::TAP::logger::expect_ ## SUFFIX (const T &a, \
|
||||||
const U &b, \
|
const U &b, \
|
||||||
const std::string &fmt, \
|
const char (&fmt)[N], \
|
||||||
Args&&... args) \
|
Args&&... args) \
|
||||||
{ \
|
{ \
|
||||||
static const std::function< \
|
expect ((a) OP (b), fmt, std::forward<Args> (args)...); \
|
||||||
bool(const T&,const U&) \
|
|
||||||
> TEST = [] (const T&t, const U&u) { return t OP u; }; \
|
|
||||||
\
|
|
||||||
expect<const T&, const U&> ( \
|
|
||||||
TEST, \
|
|
||||||
a, b, \
|
|
||||||
util::format::render ( \
|
|
||||||
fmt, \
|
|
||||||
std::forward<Args> (args)... \
|
|
||||||
) \
|
|
||||||
); \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TAP_TEST(gt, > )
|
TAP_TEST(gt, > )
|
||||||
@ -109,23 +90,18 @@ TAP_TEST(le, <=)
|
|||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
template <typename T, typename ...Args>
|
template <typename T, typename ...Args, size_t N>
|
||||||
void
|
void
|
||||||
util::TAP::logger::expect_nan (const T &t, const std::string &fmt, Args&&... args)
|
util::TAP::logger::expect_nan (const T &t, const char (&fmt)[N], Args&&... args)
|
||||||
{
|
{
|
||||||
bool(*func)(T) = std::isnan;
|
expect (std::isnan (t), fmt, std::forward<Args> (args)...);
|
||||||
expect<const T&> (
|
|
||||||
std::function<bool(const T&)> (func),
|
|
||||||
t,
|
|
||||||
util::format::render (fmt, std::forward<Args> (args)...)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
template <typename T, typename ...Args>
|
template <typename T, typename ...Args, size_t N>
|
||||||
void
|
void
|
||||||
util::TAP::logger::expect_nothrow (T &&t, const std::string &fmt, Args&&... args)
|
util::TAP::logger::expect_nothrow (T &&t, const char (&fmt)[N], Args&&... args)
|
||||||
{
|
{
|
||||||
bool success = true;
|
bool success = true;
|
||||||
|
|
||||||
@ -135,14 +111,14 @@ util::TAP::logger::expect_nothrow (T &&t, const std::string &fmt, Args&&... args
|
|||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
expect (success, util::format::render (fmt, std::forward<Args> (args)...));
|
expect (success, fmt, std::forward<Args> (args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
template <typename E, typename T, typename ...Args>
|
template <typename E, typename T, typename ...Args, size_t N>
|
||||||
void
|
void
|
||||||
util::TAP::logger::expect_throw (T &&t, const std::string &fmt, Args&&... args)
|
util::TAP::logger::expect_throw (T &&t, const char (&fmt)[N], Args&&... args)
|
||||||
{
|
{
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
|
||||||
@ -154,5 +130,5 @@ util::TAP::logger::expect_throw (T &&t, const std::string &fmt, Args&&... args)
|
|||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
expect (success, util::format::render (fmt, std::forward<Args> (args)...));
|
expect (success, fmt, std::forward<Args> (args)...);
|
||||||
}
|
}
|
||||||
|
@ -86,13 +86,13 @@ test_bool (util::TAP::logger &tap)
|
|||||||
for (auto i: positive) {
|
for (auto i: positive) {
|
||||||
argv[2] = i;
|
argv[2] = i;
|
||||||
p.scan (argv.size (), argv.data ());
|
p.scan (argv.size (), argv.data ());
|
||||||
tap.expect_eq (value, true, i, "read bool, %s", i);
|
tap.expect_eq (value, true, "read bool, %s", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto i: negative) {
|
for (auto i: negative) {
|
||||||
argv[2] = i;
|
argv[2] = i;
|
||||||
p.scan (argv.size (), argv.data ());
|
p.scan (argv.size (), argv.data ());
|
||||||
tap.expect_eq (value, false, i, "read bool, %s", i);
|
tap.expect_eq (value, false, "read bool, %s", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that invalid forms of boolean all throw exceptions
|
// Check that invalid forms of boolean all throw exceptions
|
||||||
|
@ -45,8 +45,8 @@ main (int, char**)
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (auto i: TESTS) {
|
for (auto i: TESTS) {
|
||||||
tap.expect_eq (util::rgb_to_hsv (i.rgb), i.hsv, i.name);
|
tap.expect_eq (util::rgb_to_hsv (i.rgb), i.hsv, "rgb-to-hsv %s", i.name);
|
||||||
tap.expect_eq (util::hsv_to_rgb (i.hsv), i.rgb, i.name);
|
tap.expect_eq (util::hsv_to_rgb (i.hsv), i.rgb, "hsv-to-rgb %s", i.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include "tap.hpp"
|
#include "tap.hpp"
|
||||||
#include "types.hpp"
|
#include "types.hpp"
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main ()
|
main ()
|
||||||
{
|
{
|
||||||
@ -384,8 +385,6 @@ main ()
|
|||||||
success = success && std::equal (std::begin (data), std::end (data), std::begin (t.data[j]));
|
success = success && std::equal (std::begin (data), std::end (data), std::begin (t.data[j]));
|
||||||
};
|
};
|
||||||
|
|
||||||
std::ostringstream os;
|
tap.expect (success, "ARC4 %zu", i);
|
||||||
os << "ARC4: " << i;
|
|
||||||
tap.expect (success, os.str ());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,17 +50,8 @@ main ()
|
|||||||
std::array<uint32_t,2> dec (t.enc);
|
std::array<uint32_t,2> dec (t.enc);
|
||||||
gen.decrypt (dec.data (), dec.size ());
|
gen.decrypt (dec.data (), dec.size ());
|
||||||
|
|
||||||
{
|
tap.expect (enc == t.enc, "TEA_enc %zu", i);
|
||||||
std::ostringstream os;
|
tap.expect (dec == t.dec, "TEA_dec %zu", i);
|
||||||
os << "TEA_enc " << i;
|
|
||||||
tap.expect (enc == t.enc, os.str ());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
std::ostringstream os;
|
|
||||||
os << "TEA_dec " << i;
|
|
||||||
tap.expect (dec == t.dec, os.str ());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return tap.status ();
|
return tap.status ();
|
||||||
|
@ -49,17 +49,8 @@ main ()
|
|||||||
std::array<uint32_t,2> dec (t.enc);
|
std::array<uint32_t,2> dec (t.enc);
|
||||||
gen.decrypt (dec.data (), dec.size ());
|
gen.decrypt (dec.data (), dec.size ());
|
||||||
|
|
||||||
{
|
tap.expect (enc == t.enc, "XTEA_enc %zu", i);
|
||||||
std::ostringstream os;
|
tap.expect (dec == t.dec, "XTEA_dec %zu", i);
|
||||||
os << "XTEA_enc " << i;
|
|
||||||
tap.expect (enc == t.enc, os.str ());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
std::ostringstream os;
|
|
||||||
os << "XTEA_dec " << i;
|
|
||||||
tap.expect (dec == t.dec, os.str ());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return tap.status ();
|
return tap.status ();
|
||||||
|
@ -104,17 +104,8 @@ main ()
|
|||||||
std::vector<uint32_t> dec (enc);
|
std::vector<uint32_t> dec (enc);
|
||||||
gen.decrypt (dec.data (), dec.size ());
|
gen.decrypt (dec.data (), dec.size ());
|
||||||
|
|
||||||
{
|
tap.expect (enc == t.enc, "XXTEA_enc %zu", i);
|
||||||
std::ostringstream os;
|
tap.expect (dec == t.dec, "XXTEA_dec %zu", i);
|
||||||
os << "XXTEA_enc " << i;
|
|
||||||
tap.expect (enc == t.enc, os.str ());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
std::ostringstream os;
|
|
||||||
os << "XXTEA_dec " << i;
|
|
||||||
tap.expect (dec == t.dec, os.str ());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return tap.status ();
|
return tap.status ();
|
||||||
|
@ -16,19 +16,19 @@ test_simple (util::TAP::logger &tap)
|
|||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
os << "fixed<" << type_to_string<T> () << ',' << I << ',' << E << '>';
|
os << "fixed<" << type_to_string<T> () << ',' << I << ',' << E << '>';
|
||||||
|
|
||||||
tap.expect_eq (lo, lo, os.str () + " self equality");
|
tap.expect_eq (lo, lo, "%s self equality", os.str ());
|
||||||
tap.expect_eq (hi, hi, os.str () + " self equality");
|
tap.expect_eq (hi, hi, "%s self equality", os.str ());
|
||||||
|
|
||||||
tap.expect_neq (hi, lo, os.str () + " inequality");
|
tap.expect_neq (hi, lo, "%s inequality", os.str ());
|
||||||
tap.expect_neq (lo, hi, os.str () + " inequality");
|
tap.expect_neq (lo, hi, "%s inequality", os.str ());
|
||||||
|
|
||||||
tap.expect_lt (lo, hi, os.str () + " less than");
|
tap.expect_lt (lo, hi, "%s less than", os.str ());
|
||||||
tap.expect_le (lo, hi, os.str () + " less than equal");
|
tap.expect_le (lo, hi, "%s less than equal", os.str ());
|
||||||
tap.expect_le (lo, lo, os.str () + " less than equal");
|
tap.expect_le (lo, lo, "%s less than equal", os.str ());
|
||||||
|
|
||||||
tap.expect_gt (hi, lo, os.str () + " greater than");
|
tap.expect_gt (hi, lo, "%s greater than", os.str ());
|
||||||
tap.expect_ge (lo, lo, os.str () + " greater than equal");
|
tap.expect_ge (lo, lo, "%s greater than equal", os.str ());
|
||||||
tap.expect_ge (hi, lo, os.str () + " greater than equal");
|
tap.expect_ge (hi, lo, "%s greater than equal", os.str ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
191
test/format.cpp
191
test/format.cpp
@ -5,25 +5,186 @@
|
|||||||
int
|
int
|
||||||
main (void)
|
main (void)
|
||||||
{
|
{
|
||||||
using namespace std::string_literals;
|
|
||||||
|
|
||||||
util::TAP::logger tap;
|
util::TAP::logger tap;
|
||||||
|
|
||||||
tap.expect_eq (util::format::render ("identity"), "identity"s, "identity literal");
|
#define CHECK_RENDER(fmt,res,...) do { \
|
||||||
tap.expect_eq (util::format::render ("%s", "identity"s), "identity"s, "identity string substitution");
|
auto val = util::format::render (fmt, ##__VA_ARGS__); \
|
||||||
tap.expect_eq (util::format::render ("%s", "identity" ), "identity"s, "identity char[] substitution");
|
tap.expect_eq (val, res, "render '%s'", fmt); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
tap.expect_throw<util::format::missing_error> ([] (void) {
|
CHECK_RENDER ("foo", "foo");
|
||||||
util::format::render ("%s");
|
|
||||||
}, "missing value");
|
|
||||||
|
|
||||||
tap.expect_throw<util::format::invalid_specifier<int>> ([] (void) {
|
CHECK_RENDER ("%i", "1", 1 );
|
||||||
util::format::render ("%<", 42);
|
CHECK_RENDER ("%3i", " 1", 1 );
|
||||||
}, "invalid specifier");
|
CHECK_RENDER ("%03i", "001", 1 );
|
||||||
|
CHECK_RENDER ("%.i", "", 0);
|
||||||
|
CHECK_RENDER ("% .i", " ", 0); // zero precision still requires a space
|
||||||
|
|
||||||
tap.expect_throw<util::format::format_error> ([] (void) {
|
CHECK_RENDER ("%hhi", "1", (signed char)1);
|
||||||
util::format::render ("%", 42);
|
CHECK_RENDER ("%hi", "1", (signed short)1);
|
||||||
}, "truncated specifier");
|
CHECK_RENDER ("%li", "1", (signed long)1);
|
||||||
|
CHECK_RENDER ("%lli", "1", (signed long long)1);
|
||||||
|
CHECK_RENDER ("%ji", "1", (intmax_t)1);
|
||||||
|
CHECK_RENDER ("%zi", "1", (ssize_t)1);
|
||||||
|
CHECK_RENDER ("%ti", "1", (ptrdiff_t)1);
|
||||||
|
|
||||||
return tap.status ();
|
CHECK_RENDER ("%u", "1", 1u);
|
||||||
|
CHECK_RENDER ("%03u", "001", 1u);
|
||||||
|
CHECK_RENDER ("% u", " 1", 1u);
|
||||||
|
CHECK_RENDER ("% 3u", " 1", 1u);
|
||||||
|
CHECK_RENDER ("% 03u", " 01", 1u);
|
||||||
|
CHECK_RENDER ("%-3u", "1 ", 1u);
|
||||||
|
CHECK_RENDER ("%64u", " 1", 1u);
|
||||||
|
|
||||||
|
CHECK_RENDER ("%hhu", "1", (unsigned char)1);
|
||||||
|
CHECK_RENDER ("%hu", "1", (unsigned short)1);
|
||||||
|
CHECK_RENDER ("%lu", "1", (unsigned long)1);
|
||||||
|
CHECK_RENDER ("%llu", "1", (unsigned long long)1);
|
||||||
|
CHECK_RENDER ("%ju", "1", (uintmax_t)1);
|
||||||
|
CHECK_RENDER ("%zu", "1", (size_t)1);
|
||||||
|
|
||||||
|
CHECK_RENDER ("%o", "1", 01u);
|
||||||
|
CHECK_RENDER ("%o", "13", 013u);
|
||||||
|
CHECK_RENDER ("%o", "13", 013u);
|
||||||
|
CHECK_RENDER ("%#o", "013", 013u);
|
||||||
|
|
||||||
|
CHECK_RENDER ("%x", "1", 0x1u);
|
||||||
|
CHECK_RENDER ("%x", "fe", 0xfeu);
|
||||||
|
CHECK_RENDER ("%X", "FE", 0xFEu);
|
||||||
|
CHECK_RENDER ("%#x", "0xfe", 0xfeu);
|
||||||
|
CHECK_RENDER ("%#X", "0XFE", 0xFEu);
|
||||||
|
|
||||||
|
CHECK_RENDER ("%e", "1.000000e+00", 1.);
|
||||||
|
CHECK_RENDER ("%e", "1.200000e+00", 1.2);
|
||||||
|
CHECK_RENDER ("%e", "1.234568e+00", 1.2345678);
|
||||||
|
|
||||||
|
CHECK_RENDER ("%E", "1.234568E+00", 1.2345678);
|
||||||
|
|
||||||
|
CHECK_RENDER ("%f", "1.000000", 1.);
|
||||||
|
CHECK_RENDER ("%f", "1.200000", 1.2);
|
||||||
|
CHECK_RENDER ("%f", "1.234560", 1.23456);
|
||||||
|
CHECK_RENDER ("%f", "1.234567", 1.234567);
|
||||||
|
CHECK_RENDER ("%f", "1.234568", 1.2345678);
|
||||||
|
|
||||||
|
CHECK_RENDER ("%g", "1", 1.);
|
||||||
|
CHECK_RENDER ("%g", "1.2", 1.2);
|
||||||
|
CHECK_RENDER ("%g", "1.23457", 1.2345678);
|
||||||
|
CHECK_RENDER ("%g", "0.000123457", 0.00012345678);
|
||||||
|
CHECK_RENDER ("%g", "1.23457e-05", 0.000012345678);
|
||||||
|
CHECK_RENDER ("%G", "1.23457E-05", 0.000012345678);
|
||||||
|
|
||||||
|
CHECK_RENDER ("%+e", "+1.234568e+00", 1.2345678);
|
||||||
|
CHECK_RENDER ("%+f", "+1.234568", 1.2345678);
|
||||||
|
CHECK_RENDER ("%+g", "+1.23457", 1.2345678);
|
||||||
|
CHECK_RENDER ("%+a", "+0x1.3c0ca2a5b1d5dp+0", 1.2345678);
|
||||||
|
|
||||||
|
CHECK_RENDER ("%#.e", "1.e+00", 1.2345678);
|
||||||
|
CHECK_RENDER ("%#.f", "1.", 1.2345678);
|
||||||
|
CHECK_RENDER ("%#.g", "1.", 1.2345678);
|
||||||
|
//CHECK_RENDER ("%#.a", "0x1.p+0", 1.2345678);
|
||||||
|
|
||||||
|
CHECK_RENDER ("%a", "0x1.3c0ca2a5b1d5dp+0", 1.2345678);
|
||||||
|
CHECK_RENDER ("%A", "0X1.3C0CA2A5B1D5DP+0", 1.2345678);
|
||||||
|
|
||||||
|
CHECK_RENDER ("%e", "inf", std::numeric_limits<double>::infinity ());
|
||||||
|
CHECK_RENDER ("%E", "INF", std::numeric_limits<double>::infinity ());
|
||||||
|
CHECK_RENDER ("%f", "inf", std::numeric_limits<double>::infinity ());
|
||||||
|
CHECK_RENDER ("%F", "INF", std::numeric_limits<double>::infinity ());
|
||||||
|
CHECK_RENDER ("%g", "inf", std::numeric_limits<double>::infinity ());
|
||||||
|
CHECK_RENDER ("%G", "INF", std::numeric_limits<double>::infinity ());
|
||||||
|
CHECK_RENDER ("%a", "inf", std::numeric_limits<double>::infinity ());
|
||||||
|
CHECK_RENDER ("%A", "INF", std::numeric_limits<double>::infinity ());
|
||||||
|
|
||||||
|
CHECK_RENDER ("%e", "nan", std::numeric_limits<double>::quiet_NaN ());
|
||||||
|
CHECK_RENDER ("%E", "NAN", std::numeric_limits<double>::quiet_NaN ());
|
||||||
|
CHECK_RENDER ("%f", "nan", std::numeric_limits<double>::quiet_NaN ());
|
||||||
|
CHECK_RENDER ("%F", "NAN", std::numeric_limits<double>::quiet_NaN ());
|
||||||
|
CHECK_RENDER ("%g", "nan", std::numeric_limits<double>::quiet_NaN ());
|
||||||
|
CHECK_RENDER ("%G", "NAN", std::numeric_limits<double>::quiet_NaN ());
|
||||||
|
CHECK_RENDER ("%a", "nan", std::numeric_limits<double>::quiet_NaN ());
|
||||||
|
CHECK_RENDER ("%A", "NAN", std::numeric_limits<double>::quiet_NaN ());
|
||||||
|
|
||||||
|
CHECK_RENDER ("%.f", "1", 1.2345678);
|
||||||
|
CHECK_RENDER ("%3.f", " 1", 1.2345678);
|
||||||
|
CHECK_RENDER ("%3.2f", "1.23", 1.2345678);
|
||||||
|
CHECK_RENDER ("%3.2f", "1234.57", 1234.5678);
|
||||||
|
|
||||||
|
CHECK_RENDER ("%c", "A", 'A');
|
||||||
|
|
||||||
|
CHECK_RENDER ("%s", "foo", "foo");
|
||||||
|
CHECK_RENDER ("%.s", "", "foo");
|
||||||
|
CHECK_RENDER ("%.0s", "", "foo");
|
||||||
|
CHECK_RENDER ("%.2s", "fo", "foo");
|
||||||
|
CHECK_RENDER ("%.02s", "fo", "foo");
|
||||||
|
CHECK_RENDER ("%.64s", "foo", "foo");
|
||||||
|
CHECK_RENDER ("%3.1s", " f", "foo");
|
||||||
|
CHECK_RENDER ("%-3.1s", "f ", "foo");
|
||||||
|
|
||||||
|
CHECK_RENDER ("%p", "0x1234567", (void*)0x01234567);
|
||||||
|
CHECK_RENDER ("%p", "0x1234567", (int*)0x01234567);
|
||||||
|
CHECK_RENDER ("%p", "(nil)", nullptr);
|
||||||
|
CHECK_RENDER ("%p", "(nil)", NULL);
|
||||||
|
|
||||||
|
CHECK_RENDER ("%%", "%");
|
||||||
|
CHECK_RENDER ("%10%", "%");
|
||||||
|
CHECK_RENDER ("%.%", "%");
|
||||||
|
CHECK_RENDER ("% 0-+#12.34%", "%"); // escaped conversions should largely ignore flags, width, and precision.
|
||||||
|
|
||||||
|
// multiple components
|
||||||
|
CHECK_RENDER ("%%%%", "%%");
|
||||||
|
|
||||||
|
CHECK_RENDER (" %%", " %");
|
||||||
|
CHECK_RENDER ("%% ", "% ");
|
||||||
|
CHECK_RENDER ("%% %%", "% %");
|
||||||
|
CHECK_RENDER (" %% %% ", " % % ");
|
||||||
|
|
||||||
|
CHECK_RENDER ("%u %u", "1 2", 1u, 2u);
|
||||||
|
|
||||||
|
CHECK_RENDER ("%#o %o", "010 10", 8u, 8u);
|
||||||
|
CHECK_RENDER ("%#o %o %#o", "010 10 010", 8u, 8u, 8u);
|
||||||
|
CHECK_RENDER ("%X%x%X", "FfF", 0xfu, 0xfu, 0xfu);
|
||||||
|
|
||||||
|
tap.expect_eq (util::format::render ("%u\n", 1u), "1\n", "newline");
|
||||||
|
|
||||||
|
#define CHECK_THROW(fmt,except,...) do { \
|
||||||
|
tap.expect_throw<util::format::except> ([&] { \
|
||||||
|
util::format::render (fmt, ##__VA_ARGS__); \
|
||||||
|
}, "exception '%s' for format '%s'", #except, fmt); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
CHECK_THROW("%", syntax_error);
|
||||||
|
CHECK_THROW("%_", syntax_error);
|
||||||
|
CHECK_THROW("%_u", syntax_error);
|
||||||
|
|
||||||
|
CHECK_THROW("%u", missing_error);
|
||||||
|
CHECK_THROW("%!", missing_error);
|
||||||
|
|
||||||
|
CHECK_THROW("%d", conversion_error, 1u);
|
||||||
|
CHECK_THROW("%i", conversion_error, 1u);
|
||||||
|
CHECK_THROW("%i", conversion_error, nullptr);
|
||||||
|
|
||||||
|
CHECK_THROW("%hhi", length_error, (long long)1);
|
||||||
|
CHECK_THROW("%lli", length_error, (signed char)1);
|
||||||
|
|
||||||
|
CHECK_THROW("%u", conversion_error, 1.);
|
||||||
|
CHECK_THROW("%u", conversion_error, "foo");
|
||||||
|
CHECK_THROW("%u", conversion_error, (void*)0);
|
||||||
|
CHECK_THROW("%u", conversion_error, 1);
|
||||||
|
CHECK_THROW("%u", conversion_error, nullptr);
|
||||||
|
|
||||||
|
CHECK_THROW("%hhu", length_error, (unsigned long long)1);
|
||||||
|
CHECK_THROW("%llu", length_error, (unsigned char)1);
|
||||||
|
|
||||||
|
CHECK_THROW("%f", conversion_error, 1u);
|
||||||
|
CHECK_THROW("%f", conversion_error, "foo");
|
||||||
|
CHECK_THROW("%f", conversion_error, nullptr);
|
||||||
|
|
||||||
|
CHECK_THROW("%s", conversion_error, 1u);
|
||||||
|
CHECK_THROW("%s", conversion_error, '_');
|
||||||
|
CHECK_THROW("%s", conversion_error, nullptr);
|
||||||
|
|
||||||
|
CHECK_THROW("%c", conversion_error, 1u);
|
||||||
|
CHECK_THROW("%c", conversion_error, "foo");
|
||||||
|
|
||||||
|
CHECK_THROW("%!", conversion_error, 1u);
|
||||||
}
|
}
|
||||||
|
@ -274,7 +274,7 @@ main (int, char**)
|
|||||||
util::TAP::logger tap;
|
util::TAP::logger tap;
|
||||||
|
|
||||||
for (size_t i = 0; i < elems (TESTS); ++i)
|
for (size_t i = 0; i < elems (TESTS); ++i)
|
||||||
tap.expect (TESTS[i].fun (TESTS[i].key, TESTS[i].dat, TESTS[i].res), "standard test vector %u", i);
|
tap.expect (TESTS[i].fun (TESTS[i].key, TESTS[i].dat, TESTS[i].res), "standard test vector %zu", i);
|
||||||
|
|
||||||
return tap.status ();
|
return tap.status ();
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,7 @@ main(int, char**) {
|
|||||||
obj.update (reinterpret_cast<const uint8_t*> (i.data), strlen (i.data));
|
obj.update (reinterpret_cast<const uint8_t*> (i.data), strlen (i.data));
|
||||||
obj.finish ();
|
obj.finish ();
|
||||||
|
|
||||||
tap.expect_eq (obj.digest (), i.output, i.msg);
|
tap.expect_eq (obj.digest (), i.output, "%s", i.msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform 'million-a' check
|
// Perform 'million-a' check
|
||||||
|
@ -66,7 +66,7 @@ main (int, char**)
|
|||||||
obj.update (reinterpret_cast<const uint8_t*> (i.input), strlen (i.input));
|
obj.update (reinterpret_cast<const uint8_t*> (i.input), strlen (i.input));
|
||||||
obj.finish ();
|
obj.finish ();
|
||||||
|
|
||||||
tap.expect_eq (obj.digest (), i.output, i.msg);
|
tap.expect_eq (obj.digest (), i.output, "%s", i.msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
return tap.status ();
|
return tap.status ();
|
||||||
|
@ -55,7 +55,7 @@ main (int, char **) {
|
|||||||
obj.update (reinterpret_cast<const uint8_t*> (i.input), strlen (i.input));
|
obj.update (reinterpret_cast<const uint8_t*> (i.input), strlen (i.input));
|
||||||
obj.finish ();
|
obj.finish ();
|
||||||
|
|
||||||
tap.expect_eq (obj.digest (), i.output, i.msg);
|
tap.expect_eq (obj.digest (), i.output, "%s", i.msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
return tap.status ();
|
return tap.status ();
|
||||||
|
10
test/ip.cpp
10
test/ip.cpp
@ -23,9 +23,8 @@ test_good (util::TAP::logger &tap)
|
|||||||
{ "127.0.0.1", { 127, 0, 0, 1 }, "localhost" }
|
{ "127.0.0.1", { 127, 0, 0, 1 }, "localhost" }
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const auto &i: TESTS) {
|
for (const auto &i: TESTS)
|
||||||
tap.expect_eq (ipv4::ip::parse (i.str), i.ip, i.msg);
|
tap.expect_eq (ipv4::ip::parse (i.str), i.ip, "%s", i.msg);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -43,9 +42,8 @@ test_bad (util::TAP::logger &tap)
|
|||||||
{ "256.0.0.1", "overflow" }
|
{ "256.0.0.1", "overflow" }
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const auto &i: TESTS) {
|
for (const auto &i: TESTS)
|
||||||
tap.expect_throw<ipv4::error> ([&] { ipv4::ip::parse (i.str); }, i.msg);
|
tap.expect_throw<ipv4::error> ([&] { ipv4::ip::parse (i.str); }, "%s", i.msg);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ main (int, char**)
|
|||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
test.expect (ok, i.name);
|
test.expect (ok, "%s", i.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -33,7 +33,7 @@ main (void)
|
|||||||
for (const auto &t: TESTS) {
|
for (const auto &t: TESTS) {
|
||||||
constexpr float TOLERANCE = 0.00001f;
|
constexpr float TOLERANCE = 0.00001f;
|
||||||
auto root = util::roots::bisection (t.lo, t.hi, t.func, TOLERANCE);
|
auto root = util::roots::bisection (t.lo, t.hi, t.func, TOLERANCE);
|
||||||
tap.expect_eq (root, t.root, t.msg);
|
tap.expect_eq (root, t.root, "%s", t.msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
return tap.status ();
|
return tap.status ();
|
||||||
|
@ -47,7 +47,7 @@ test_polar (util::TAP::logger &tap)
|
|||||||
auto in_cart = t.cartesian;
|
auto in_cart = t.cartesian;
|
||||||
auto to_cart = util::polar_to_cartesian (t.polar);
|
auto to_cart = util::polar_to_cartesian (t.polar);
|
||||||
|
|
||||||
tap.expect_lt ((in_cart - to_cart).magnitude (), 0.00001f, t.desc);
|
tap.expect_lt ((in_cart - to_cart).magnitude (), 0.00001f, "%s", t.desc);
|
||||||
|
|
||||||
// Compare polar representations. Make sure to normalise them first.
|
// Compare polar representations. Make sure to normalise them first.
|
||||||
auto in_polar = t.polar;
|
auto in_polar = t.polar;
|
||||||
@ -56,7 +56,7 @@ test_polar (util::TAP::logger &tap)
|
|||||||
in_polar[1] = std::fmod (in_polar[1], 2 * util::PI<float>);
|
in_polar[1] = std::fmod (in_polar[1], 2 * util::PI<float>);
|
||||||
to_polar[1] = std::fmod (to_polar[1], 2 * util::PI<float>);
|
to_polar[1] = std::fmod (to_polar[1], 2 * util::PI<float>);
|
||||||
|
|
||||||
tap.expect_eq (in_polar, to_polar, t.desc);
|
tap.expect_eq (in_polar, to_polar, "%s", t.desc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ main () {
|
|||||||
for (const auto &i: PARSE_TESTS) {
|
for (const auto &i: PARSE_TESTS) {
|
||||||
util::version v (i.str);
|
util::version v (i.str);
|
||||||
|
|
||||||
tap.expect (std::equal (v.begin (), v.end (), i.parts) && v.release == i.release, i.msg);
|
tap.expect (std::equal (v.begin (), v.end (), i.parts) && v.release == i.release, "%s", i.msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user