mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-04 19:25:51 +00:00
Per XLS-0095, we are taking steps to rename ripple(d) to xrpl(d). This change specifically removes all copyright notices referencing Ripple, XRPLF, and certain affiliated contributors upon mutual agreement, so the notice in the LICENSE.md file applies throughout. Copyright notices referencing external contributions remain as-is. Duplicate verbiage is also removed.
184 lines
4.1 KiB
C++
184 lines
4.1 KiB
C++
#ifndef XRPL_PROTOCOL_BOOK_H_INCLUDED
|
|
#define XRPL_PROTOCOL_BOOK_H_INCLUDED
|
|
|
|
#include <xrpl/basics/CountedObject.h>
|
|
#include <xrpl/basics/base_uint.h>
|
|
#include <xrpl/protocol/Issue.h>
|
|
|
|
#include <boost/utility/base_from_member.hpp>
|
|
|
|
namespace ripple {
|
|
|
|
/** Specifies an order book.
|
|
The order book is a pair of Issues called in and out.
|
|
@see Issue.
|
|
*/
|
|
class Book final : public CountedObject<Book>
|
|
{
|
|
public:
|
|
Issue in;
|
|
Issue out;
|
|
std::optional<uint256> domain;
|
|
|
|
Book()
|
|
{
|
|
}
|
|
|
|
Book(
|
|
Issue const& in_,
|
|
Issue const& out_,
|
|
std::optional<uint256> const& domain_)
|
|
: in(in_), out(out_), domain(domain_)
|
|
{
|
|
}
|
|
};
|
|
|
|
bool
|
|
isConsistent(Book const& book);
|
|
|
|
std::string
|
|
to_string(Book const& book);
|
|
|
|
std::ostream&
|
|
operator<<(std::ostream& os, Book const& x);
|
|
|
|
template <class Hasher>
|
|
void
|
|
hash_append(Hasher& h, Book const& b)
|
|
{
|
|
using beast::hash_append;
|
|
hash_append(h, b.in, b.out);
|
|
if (b.domain)
|
|
hash_append(h, *(b.domain));
|
|
}
|
|
|
|
Book
|
|
reversed(Book const& book);
|
|
|
|
/** Equality comparison. */
|
|
/** @{ */
|
|
[[nodiscard]] inline constexpr bool
|
|
operator==(Book const& lhs, Book const& rhs)
|
|
{
|
|
return (lhs.in == rhs.in) && (lhs.out == rhs.out) &&
|
|
(lhs.domain == rhs.domain);
|
|
}
|
|
/** @} */
|
|
|
|
/** Strict weak ordering. */
|
|
/** @{ */
|
|
[[nodiscard]] inline constexpr std::weak_ordering
|
|
operator<=>(Book const& lhs, Book const& rhs)
|
|
{
|
|
if (auto const c{lhs.in <=> rhs.in}; c != 0)
|
|
return c;
|
|
if (auto const c{lhs.out <=> rhs.out}; c != 0)
|
|
return c;
|
|
|
|
// Manually compare optionals
|
|
if (lhs.domain && rhs.domain)
|
|
return *lhs.domain <=> *rhs.domain; // Compare values if both exist
|
|
if (!lhs.domain && rhs.domain)
|
|
return std::weak_ordering::less; // Empty is considered less
|
|
if (lhs.domain && !rhs.domain)
|
|
return std::weak_ordering::greater; // Non-empty is greater
|
|
|
|
return std::weak_ordering::equivalent; // Both are empty
|
|
}
|
|
/** @} */
|
|
|
|
} // namespace ripple
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
namespace std {
|
|
|
|
template <>
|
|
struct hash<ripple::Issue>
|
|
: private boost::base_from_member<std::hash<ripple::Currency>, 0>,
|
|
private boost::base_from_member<std::hash<ripple::AccountID>, 1>
|
|
{
|
|
private:
|
|
using currency_hash_type =
|
|
boost::base_from_member<std::hash<ripple::Currency>, 0>;
|
|
using issuer_hash_type =
|
|
boost::base_from_member<std::hash<ripple::AccountID>, 1>;
|
|
|
|
public:
|
|
hash() = default;
|
|
|
|
using value_type = std::size_t;
|
|
using argument_type = ripple::Issue;
|
|
|
|
value_type
|
|
operator()(argument_type const& value) const
|
|
{
|
|
value_type result(currency_hash_type::member(value.currency));
|
|
if (!isXRP(value.currency))
|
|
boost::hash_combine(
|
|
result, issuer_hash_type::member(value.account));
|
|
return result;
|
|
}
|
|
};
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
template <>
|
|
struct hash<ripple::Book>
|
|
{
|
|
private:
|
|
using issue_hasher = std::hash<ripple::Issue>;
|
|
using uint256_hasher = ripple::uint256::hasher;
|
|
|
|
issue_hasher m_issue_hasher;
|
|
uint256_hasher m_uint256_hasher;
|
|
|
|
public:
|
|
hash() = default;
|
|
|
|
using value_type = std::size_t;
|
|
using argument_type = ripple::Book;
|
|
|
|
value_type
|
|
operator()(argument_type const& value) const
|
|
{
|
|
value_type result(m_issue_hasher(value.in));
|
|
boost::hash_combine(result, m_issue_hasher(value.out));
|
|
|
|
if (value.domain)
|
|
boost::hash_combine(result, m_uint256_hasher(*value.domain));
|
|
|
|
return result;
|
|
}
|
|
};
|
|
|
|
} // namespace std
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
namespace boost {
|
|
|
|
template <>
|
|
struct hash<ripple::Issue> : std::hash<ripple::Issue>
|
|
{
|
|
hash() = default;
|
|
|
|
using Base = std::hash<ripple::Issue>;
|
|
// VFALCO NOTE broken in vs2012
|
|
// using Base::Base; // inherit ctors
|
|
};
|
|
|
|
template <>
|
|
struct hash<ripple::Book> : std::hash<ripple::Book>
|
|
{
|
|
hash() = default;
|
|
|
|
using Base = std::hash<ripple::Book>;
|
|
// VFALCO NOTE broken in vs2012
|
|
// using Base::Base; // inherit ctors
|
|
};
|
|
|
|
} // namespace boost
|
|
|
|
#endif
|