我正在编写一个软件,将 GenericOrder (包含数量,价格,方式和时间戳)存储为shared_ptr。
我已阅读Boost文档并成功使用三个索引定义 MultiIndexOrderContainer :方式,时间戳和价格。
但我没有找到一种方法来同时使用多个索引迭代特定的订单。
#include <memory>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/member.hpp>
using namespace ::boost;
using namespace ::boost::multi_index;
enum class Way
{
UNDEFINED,
BUY,
SELL
};
template <typename QuantityType, typename PriceType>
struct GenericOrder
{
explicit GenericOrder(const Way way, const QuantityType& quantity, const PriceType& price, const long long& timestamp)
: way_(way), quantity_(quantity), price_(price), timestamp_(timestamp)
{
}
~GenericOrder() = default;
GenericOrder(const GenericOrder&) = delete;
GenericOrder& operator=(const GenericOrder&) = delete;
Way way_;
QuantityType quantity_;
PriceType price_;
long long timestamp_ = -1;
};
// Aliases
using QuantityType = int;
using PriceType = int;
using OrderType = GenericOrder<QuantityType, PriceType>;
using PointerType = std::shared_ptr<OrderType>;
struct way {};
struct timestamp {};
struct price {};
using MultiIndexOrderContainer = multi_index_container<PointerType,
indexed_by<
ordered_non_unique<tag<way>, member<OrderType, decltype(OrderType::way_), &OrderType::way_ >>,
ordered_non_unique<tag<timestamp>, member<OrderType, decltype(OrderType::timestamp_), &OrderType::timestamp_ >>,
ordered_non_unique<tag<price>, member<OrderType, decltype(OrderType::price_), &OrderType::price_>>
>
>;
int main()
{
MultiIndexOrderContainer c;
// Inserting some orders
c.insert(std::make_shared<OrderType>(Way::BUY, 10, 15, 0));
c.insert(std::make_shared<OrderType>(Way::BUY, 10, 14, 1));
c.insert(std::make_shared<OrderType>(Way::BUY, 10, 13, 2));
c.insert(std::make_shared<OrderType>(Way::SELL, 10, 16, 3));
c.insert(std::make_shared<OrderType>(Way::SELL, 10, 17, 4));
c.insert(std::make_shared<OrderType>(Way::SELL, 10, 18, 5));
return 0;
}
我想重复:
我怎样才能做到这一点?
答案 0 :(得分:2)
Boost.MultiIndex没有提供任何特殊的机制来混合不同索引引起的顺序:你建议的结构基本上是查询第一个参数,然后对返回的范围进行线性扫描。
另一方面,如果您的查询始终采用格式(attr1,attr2,attr3),则可以使用composite keys加快速度。在您的特定情况下,您可以使用复合键(way_
,price_
,timestamp_
)
<强> Live On Coliru 强>
#include <memory>
#include <iostream>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/composite_key.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/member.hpp>
using namespace ::boost;
using namespace ::boost::multi_index;
enum class Way
{
UNDEFINED,
BUY,
SELL
};
template <typename QuantityType, typename PriceType>
struct GenericOrder
{
explicit GenericOrder(const Way way, const QuantityType& quantity, const PriceType& price, const long long& timestamp)
: way_(way), quantity_(quantity), price_(price), timestamp_(timestamp)
{
}
~GenericOrder() = default;
GenericOrder(const GenericOrder&) = delete;
GenericOrder& operator=(const GenericOrder&) = delete;
Way way_;
QuantityType quantity_;
PriceType price_;
long long timestamp_ = -1;
};
template <typename QuantityType, typename PriceType>
std::ostream& operator<<(std::ostream& os,const GenericOrder<QuantityType,PriceType>& o)
{
switch(o.way_){
case Way::UNDEFINED: os<<"UNDEFINED, ";break;
case Way::BUY: os<<"BUY, ";break;
case Way::SELL: os<<"SELL, ";break;
}
return os<<o.price_<<", "<<o.timestamp_<<"\n";
}
// Aliases
using QuantityType = int;
using PriceType = int;
using OrderType = GenericOrder<QuantityType, PriceType>;
using PointerType = std::shared_ptr<OrderType>;
struct way {};
struct timestamp {};
struct price {};
using MultiIndexOrderContainer = multi_index_container<PointerType,
indexed_by<
ordered_non_unique<
composite_key<
OrderType,
member<OrderType, decltype(OrderType::way_), &OrderType::way_ >,
member<OrderType, decltype(OrderType::price_), &OrderType::price_>,
member<OrderType, decltype(OrderType::timestamp_), &OrderType::timestamp_ >
>
>
>
>;
int main()
{
MultiIndexOrderContainer c;
// Inserting some orders
c.insert(std::make_shared<OrderType>(Way::BUY, 10, 15, 0));
c.insert(std::make_shared<OrderType>(Way::BUY, 10, 14, 1));
c.insert(std::make_shared<OrderType>(Way::BUY, 10, 13, 2));
c.insert(std::make_shared<OrderType>(Way::BUY, 10, 15, 1));
c.insert(std::make_shared<OrderType>(Way::SELL, 10, 16, 3));
c.insert(std::make_shared<OrderType>(Way::SELL, 10, 17, 4));
c.insert(std::make_shared<OrderType>(Way::SELL, 10, 18, 5));
std::cout<<"Buying orders for 15, sorted by timestamp\n";
auto p=c.equal_range(std::make_tuple(Way::BUY,15));
while(p.first!=p.second)std::cout<<**p.first++;
std::cout<<"Cheapest selling order\n";
std::cout<<**c.lower_bound(Way::SELL);
std::cout<<"Costliest buying order\n";
std::cout<<**--c.upper_bound(Way::BUY);
return 0;
}