Boost Multi-Index Custom Composite Key Comparer

I am looking to write a custom mapper for the boost index ordered_non_uniqueusing a composite key. I'm not quite sure how to do this. Boost has composite_key_comparer, but this will not work for me, because one of the mappings for a key member depends on the previous member. This is a simplified example, but I want the index to sort in descending order third_when second_is β€œA”, storing 0 values ​​for third_, and use std :: less in all other cases. Hope this makes sense. I would like the code below to print:

3,BLAH,A,0
5,BLAH,A,11
2,BLAH,A,10
4,BLAH,A,9
1,BLAH,A,8

Code will be replaced WHOT GOERE HERE ??? . Thanks for any help.

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/key_extractors.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/composite_key.hpp>
#include <iostream>

namespace bmi = boost::multi_index;
namespace bt = boost::tuples;

struct Widget
{
  Widget (const std::string& id, const std::string& f, char s, unsigned int t)
  : id_(id)
  , first_(f)
  , second_(s)
  , third_(t)
  { }

  ~Widget () { }

  std::string id_;
  std::string first_;
  char second_;
  unsigned int third_;
};

std::ostream& operator<< (std::ostream& os, const Widget& w)
{
  os << w.id_ << "," << w.first_ << "," << w.second_ << "," << w.third_;
  return os;
}

struct id_index { };
struct other_index { };

typedef bmi::composite_key<
  Widget*,
  bmi::member<Widget, std::string, &Widget::first_>,
  bmi::member<Widget, char, &Widget::second_>,
  bmi::member<Widget, unsigned int, &Widget::third_>
> other_key;

typedef bmi::multi_index_container<
  Widget*,
  bmi::indexed_by<
    bmi::ordered_unique<
      bmi::tag<id_index>,
      bmi::member<Widget, std::string, &Widget::id_>
    >,
    bmi::ordered_non_unique<
      bmi::tag<other_index>,
      other_key,
      ***************WHAT GOES HERE???***************
    >
  >
> widget_set;

typedef widget_set::index<other_index>::type widgets_by_other;
typedef widgets_by_other::iterator other_index_itr;

int main ()
{
  widget_set widgets;
  widgets_by_other& wbo_index = widgets.get<other_index>();
  Widget* w;

  w = new Widget("1", "BLAH", 'A', 8);
  widgets.insert(w);
  w = new Widget("2", "BLAH", 'A', 10);
  widgets.insert(w);
  w = new Widget("3", "BLAH", 'A', 0);
  widgets.insert(w);
  w = new Widget("4", "BLAH", 'A', 9);
  widgets.insert(w);
  w = new Widget("5", "BLAH", 'A', 11);
  widgets.insert(w);

  std::pair<other_index_itr,other_index_itr> range =
    wbo_index.equal_range(boost::make_tuple("BLAH", 'A'));

  while (range.first != range.second)
  {
    std::cout << *(*range.first) << std::endl;
    ++range.first;
  }

  return 0;
}
+3
1

, .

:

STL, , , , .

, ( " " ):

- , .

, :

  • ,
  • Boost.MultiIndex,

, , , , , , .

struct WidgetComparer
{
  bool operator()(const Widget& lhs, const Widget& rhs) const
  {
    if (lhs._second == 'A' && rhs._second == 'A')
    {
      return lhs._third == 0 || rhs._third < lhs._third;
    }
    else
    {
      return lhs._third < rhs._third;
    }
  } // operator()
};

. " " <Widget> "WHAT GOES HERE" WidgetComparer.

!

, "" . , (, ), . (, , , std:: less).

"operator <" Widget std:: less. , , , . , , , .

, .

+3

Source: https://habr.com/ru/post/1715936/


All Articles