Skip to content

Instantly share code, notes, and snippets.

@blockspacer
Created January 31, 2023 19:39
Show Gist options
  • Save blockspacer/6e3d29f0c081dddb36f779c15cf786eb to your computer and use it in GitHub Desktop.
Save blockspacer/6e3d29f0c081dddb36f779c15cf786eb to your computer and use it in GitHub Desktop.
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/composite_key.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <string>
#include <boost/range/adaptors.hpp>
#include <vector>
#include <iostream>
//#include <boost/bind.hpp>
#include <boost/range.hpp>
#include <boost/foreach.hpp>
#include <boost/iterator/filter_iterator.hpp>
#include <boost/range/iterator_range.hpp>
#include <iostream>
using namespace std;
using namespace boost;
typedef boost::iterator_range<vector<int>::iterator> int_range;
/*template< class Range, class Pred >
boost::iterator_range< boost::filter_iterator< Pred, typename boost::range_iterator<typenameRange::value_type>::type > >
make_filter_range( Range& begin_rng, Range& end_rng, Pred pred ) {
return boost::make_iterator_range(
boost::make_filter_iterator(pred, begin_rng, end_rng),
boost::make_filter_iterator(pred, end_rng, end_rng) );
}*/
template< class Iter, class Range, class Pred >
boost::iterator_range< boost::filter_iterator< Pred, typename boost::range_iterator<Range>::type > >
make_filter_range( Range& rng, Iter& begin_rng, Iter& end_rng, Pred pred ) {
return boost::make_iterator_range(
boost::make_filter_iterator(pred, begin_rng, end_rng),
boost::make_filter_iterator(pred, end_rng, end_rng) );
}
using boost::adaptors::filtered;
using namespace boost::multi_index;
struct SatData {
std::string sat_system;
std::string band;
int index;
uint64_t time;
double data;
SatData(
const std::string& ss,
const std::string& b,
const int& i,
const uint64_t& t,
const double& d) :
sat_system(ss), band(b), index(i), time(t), data(d) {}
};
struct ByGroupID {};
struct ByBand {};
using SatDataset =
multi_index_container<
SatData, indexed_by<
ordered_non_unique<
boost::multi_index::tag<ByGroupID>,
composite_key<
SatData,
member<SatData, std::string, &SatData::sat_system>,
member<SatData, std::string, &SatData::band>,
member<SatData, uint64_t, &SatData::time>,
member<SatData, int, &SatData::index>
> // composite key
> // ordered_not_unique
, ordered_non_unique<
boost::multi_index::tag<ByBand>,
composite_key<
SatData,
member<SatData, std::string, &SatData::band>,
member<SatData, std::string, &SatData::sat_system>,
member<SatData, uint64_t, &SatData::time>,
member<SatData, int, &SatData::index>
> // composite key
> // ordered_not_unique
> // indexed_by
>; // multi_index_container
template<typename Iter>
void process(Iter first)
{
std::cout
<< first->sat_system << "\t|"
<< first->band << "\t|"
<< first->index << "\t|"
<< first->time << "\t|"
<< first->data << "\t|"
<< "\n";
}
template<typename Iter>
void process(const Iter& start, const Iter& end)
{
/*if (start < end) {
return;
}*/
if (start == end) {
//process(start);
return;
}
for(auto first = start, last = end; first != last; first++) {
process(first);
}
}
int main()
{
SatDataset s = {
{"UPD_PLU" , "L1" , 1 , 10, 0.112},
{"GPS" , "L1" , 1 , 11, 0.201},
{"GPS" , "L1" , 1 , 12, 0.100},
{"GPS" , "L2" , 1 , 10, 0.098},
{"GPS" , "L2" , 1 , 11, 0.134},
{"GPS" , "L2" , 1 , 12, 0.167},
{"GPS" , "L2" , 4 , 11, 0.199},
{"GPS" , "L2" , 4 , 12, 0.204},
{"GALILEO" , "E5b" , 2 , 10, 0.056},
{"GLONASS" , "G1" , 1 , 10, 0.123},
{"GLONASS" , "G1" , 1 , 11, 0.222},
{"GLONASS" , "G1" , 2 , 10, 0.115},
};
auto &by_group_id = s.get<ByGroupID>();
//auto filtered_group_id = by_group_id | filtered([](const SatData&){return true;});
//process(range.begin());
for(auto first = by_group_id.begin(), last = by_group_id.end(); first != last; ) {
auto next = by_group_id.upper_bound(std::make_tuple(
first->sat_system));
std::cout
<< "\n====================== GROUP: "
<< first->sat_system << "\t|"
<< first->band << "\t|"
<< first->index << "\t|"
<< first->time << "\t|"
<< std::distance(first, next) << "====================== \n";
//auto range = boost::make_iterator_range(first, next);
//process(filter_range.begin());
//process(filter_range.end());
auto filter_range = make_filter_range(by_group_id, first, next, [](const SatData& elem){return elem.band == "L1";});
process(filter_range.begin(), filter_range.end());
/*std::cout
<< "\n====================== GROUP: "
<< first->sat_system << "\t|"
<< first->band << "\t|"
<< first->index << "\t|"
<< first->time << "\t|"
<< std::distance(first, next) << "====================== \n";
process(first, next);*/
first = next;
}
auto &by_band = s.get<ByBand>();
//auto filtered_group_id = by_group_id | filtered([](const SatData&){return true;});
//process(range.begin());
for(auto first = by_band.begin(), last = by_band.end(); first != last; ) {
auto next = by_band.upper_bound(std::make_tuple(
first->band));
std::cout
<< "\n====================== BAND: "
<< first->sat_system << "\t|"
<< first->band << "\t|"
<< first->index << "\t|"
<< first->time << "\t|"
<< std::distance(first, next) << "====================== \n";
//auto range = boost::make_iterator_range(first, next);
//process(filter_range.begin());
//process(filter_range.end());
auto filter_range = make_filter_range(by_band, first, next, [](const SatData& elem){return elem.sat_system != "GLONASS";});
process(filter_range.begin(), filter_range.end());
/*std::cout
<< "\n====================== BAND: "
<< first->sat_system << "\t|"
<< first->band << "\t|"
<< first->index << "\t|"
<< first->time << "\t|"
<< std::distance(first, next) << "====================== \n";
process(first, next);*/
first = next;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment