mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
New Zero struct implements "compare with zero."
* Zero lets classes efficiently compare with 0, so you can use constructors like x < zero or y != zero. * New BEAST_CONSTEXPR to handle Windows/C++11 differences regarding the constexpr specifier.
This commit is contained in:
@@ -24,13 +24,8 @@
|
||||
#ifndef BEAST_CONFIG_COMPILERCONFIG_H_INCLUDED
|
||||
#define BEAST_CONFIG_COMPILERCONFIG_H_INCLUDED
|
||||
|
||||
// This file has to work when included in a C source file.
|
||||
|
||||
#ifndef BEAST_CONFIG_PLATFORMCONFIG_H_INCLUDED
|
||||
#error "PlatformConfig.h must come first!"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include "PlatformConfig.h"
|
||||
|
||||
// This file defines miscellaneous macros for debugging, assertions, etc.
|
||||
|
||||
@@ -47,6 +42,15 @@
|
||||
# define BEAST_CDECL
|
||||
#endif
|
||||
|
||||
/** This macro fixes C++'s constexpr for VS2012, which doesn't understand it.
|
||||
*/
|
||||
#if BEAST_MSVC
|
||||
# define BEAST_CONSTEXPR const
|
||||
#else
|
||||
# define BEAST_CONSTEXPR constexpr
|
||||
#endif
|
||||
|
||||
|
||||
// Debugging and assertion macros
|
||||
|
||||
#if BEAST_LOG_ASSERTIONS || BEAST_DEBUG
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
// MODULES: ../../crypto/impl/Sha256.cpp
|
||||
// MODULES: ../../crypto/impl/Sha256.cpp ../../container/impl/spookyv2.cpp
|
||||
|
||||
#if BEAST_INCLUDE_BEASTCONFIG
|
||||
#include "../../../BeastConfig.h"
|
||||
@@ -131,7 +131,7 @@ public:
|
||||
static std::size_t const bytes = bits / 8;
|
||||
|
||||
template <class Int>
|
||||
static
|
||||
static
|
||||
unsigned_integer
|
||||
from_number (Int v)
|
||||
{
|
||||
@@ -167,7 +167,7 @@ public:
|
||||
{
|
||||
for (std::size_t i (0); i < size; ++i)
|
||||
s <<
|
||||
std::hex <<
|
||||
std::hex <<
|
||||
std::setfill ('0') <<
|
||||
std::setw (2*sizeof(UInt)) <<
|
||||
v.m_vec[i]
|
||||
@@ -293,7 +293,7 @@ public:
|
||||
"i=" << std::setw(2) << i << " " <<
|
||||
"sha256=0x" << d_ << " " <<
|
||||
"hash=0x" <<
|
||||
std::setfill ('0') <<
|
||||
std::setfill ('0') <<
|
||||
std::setw (2*sizeof(std::size_t)) << result
|
||||
;
|
||||
pass();
|
||||
|
||||
@@ -31,3 +31,4 @@
|
||||
|
||||
#include "tests/bassert.test.cpp"
|
||||
#include "tests/empty_base_optimization.test.cpp"
|
||||
#include "tests/Zero.test.cpp"
|
||||
|
||||
140
src/beast/beast/utility/Zero.h
Normal file
140
src/beast/beast/utility/Zero.h
Normal file
@@ -0,0 +1,140 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2014, Tom Ritchford <tom@swirly.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_UTILITY_ZERO_H_INCLUDED
|
||||
#define BEAST_UTILITY_ZERO_H_INCLUDED
|
||||
|
||||
#include "../config/CompilerConfig.h"
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** Zero allows classes to offer efficient comparisons to zero.
|
||||
|
||||
Zero is a struct to allow classes to efficiently compare with zero without
|
||||
requiring an rvalue construction.
|
||||
|
||||
It's often the case that we have classes which combine a number and a unit.
|
||||
In such cases, comparisons like t > 0 or t != 0 make sense, but comparisons
|
||||
like t > 1 or t != 1 do not.
|
||||
|
||||
The class Zero allows such comparisons to be easily made.
|
||||
|
||||
The comparing class T either needs to have a method called signum() which
|
||||
returns a positive number, 0, or a negative; or there needs to be a signum
|
||||
function which resolves in the namespace which takes an instance of T and
|
||||
returns a positive, zero or negative number.
|
||||
*/
|
||||
|
||||
struct Zero {};
|
||||
|
||||
namespace {
|
||||
|
||||
static BEAST_CONSTEXPR Zero zero{};
|
||||
|
||||
} // namespace
|
||||
|
||||
/** The default implementation of signum calls the method on the class.
|
||||
|
||||
Calls to signum must be made from a namespace that does not include
|
||||
overloads of the function.
|
||||
*/
|
||||
template <typename T>
|
||||
auto signum(T const& t) -> decltype(t.signum()) {
|
||||
return t.signum();
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
namespace zero_helper {
|
||||
|
||||
template <class T>
|
||||
auto call_signum (T const& t) -> decltype(signum(t)) {
|
||||
return signum(t);
|
||||
}
|
||||
|
||||
} // zero_helper
|
||||
} // detail
|
||||
|
||||
/** Handle operators where T is on the left side using signum. */
|
||||
template <typename T>
|
||||
bool operator==(T const& t, Zero) {
|
||||
return detail::zero_helper::call_signum(t) == 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool operator!=(T const& t, Zero) {
|
||||
return detail::zero_helper::call_signum(t) != 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool operator>(T const& t, Zero) {
|
||||
return detail::zero_helper::call_signum(t) > 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool operator>=(T const& t, Zero) {
|
||||
return detail::zero_helper::call_signum(t) >= 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool operator<(T const& t, Zero) {
|
||||
return detail::zero_helper::call_signum(t) < 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool operator<=(T const& t, Zero) {
|
||||
return detail::zero_helper::call_signum(t) <= 0;
|
||||
}
|
||||
|
||||
|
||||
/** Handle operators where T is on the right side by reversing the operation,
|
||||
so that T is on the left side.
|
||||
*/
|
||||
template <typename T>
|
||||
bool operator==(Zero, T const& t) {
|
||||
return t == zero;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool operator!=(Zero, T const& t) {
|
||||
return t != zero;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool operator>(Zero, T const& t) {
|
||||
return t < zero;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool operator>=(Zero, T const& t) {
|
||||
return t <= zero;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool operator<(Zero, T const& t) {
|
||||
return t > zero;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool operator<=(Zero, T const& t) {
|
||||
return t >= zero;
|
||||
}
|
||||
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
136
src/beast/beast/utility/tests/Zero.test.cpp
Normal file
136
src/beast/beast/utility/tests/Zero.test.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2014, Nikolaos D. Bougalis <nikb@bougalis.net>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include "../Zero.h"
|
||||
|
||||
#include "../../unit_test/suite.h"
|
||||
|
||||
namespace beast {
|
||||
|
||||
struct adl_tester {};
|
||||
|
||||
int signum (adl_tester) { return 0; }
|
||||
|
||||
|
||||
namespace detail {
|
||||
|
||||
struct adl_tester2 {};
|
||||
|
||||
int signum (adl_tester2) { return 0; }
|
||||
|
||||
} // detail
|
||||
|
||||
class Zero_test : public beast::unit_test::suite
|
||||
{
|
||||
private:
|
||||
struct IntegerWrapper
|
||||
{
|
||||
int value;
|
||||
|
||||
IntegerWrapper (int v)
|
||||
: value (v)
|
||||
{
|
||||
}
|
||||
|
||||
int signum() const
|
||||
{
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
void expect_same(bool result, bool correct, char const* message)
|
||||
{
|
||||
expect(result == correct, message);
|
||||
}
|
||||
|
||||
void
|
||||
test_lhs_zero (IntegerWrapper x)
|
||||
{
|
||||
expect_same (x >= zero, x.signum () >= 0,
|
||||
"lhs greater-than-or-equal-to");
|
||||
expect_same (x > zero, x.signum () > 0,
|
||||
"lhs greater than");
|
||||
expect_same (x == zero, x.signum () == 0,
|
||||
"lhs equal to");
|
||||
expect_same (x != zero, x.signum () != 0,
|
||||
"lhs not equal to");
|
||||
expect_same (x < zero, x.signum () < 0,
|
||||
"lhs less than");
|
||||
expect_same (x <= zero, x.signum () <= 0,
|
||||
"lhs less-than-or-equal-to");
|
||||
}
|
||||
|
||||
void
|
||||
test_lhs_zero ()
|
||||
{
|
||||
testcase ("lhs zero");
|
||||
|
||||
test_lhs_zero(-7);
|
||||
test_lhs_zero(0);
|
||||
test_lhs_zero(32);
|
||||
}
|
||||
|
||||
void
|
||||
test_rhs_zero (IntegerWrapper x)
|
||||
{
|
||||
expect_same (zero >= x, 0 >= x.signum (),
|
||||
"rhs greater-than-or-equal-to");
|
||||
expect_same (zero > x, 0 > x.signum (),
|
||||
"rhs greater than");
|
||||
expect_same (zero == x, 0 == x.signum (),
|
||||
"rhs equal to");
|
||||
expect_same (zero != x, 0 != x.signum (),
|
||||
"rhs not equal to");
|
||||
expect_same (zero < x, 0 < x.signum (),
|
||||
"rhs less than");
|
||||
expect_same (zero <= x, 0 <= x.signum (),
|
||||
"rhs less-than-or-equal-to");
|
||||
}
|
||||
|
||||
void
|
||||
test_rhs_zero ()
|
||||
{
|
||||
testcase ("rhs zero");
|
||||
|
||||
test_rhs_zero(-4);
|
||||
test_rhs_zero(0);
|
||||
test_rhs_zero(64);
|
||||
}
|
||||
|
||||
void
|
||||
test_adl ()
|
||||
{
|
||||
expect (adl_tester{} == zero, "ADL failure!");
|
||||
expect (detail::adl_tester2{} == zero, "ADL failure!");
|
||||
}
|
||||
|
||||
void
|
||||
run()
|
||||
{
|
||||
test_lhs_zero ();
|
||||
test_rhs_zero ();
|
||||
test_adl ();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(Zero, types, beast);
|
||||
|
||||
}
|
||||
0
src/beast/tests.sh
Normal file → Executable file
0
src/beast/tests.sh
Normal file → Executable file
Reference in New Issue
Block a user