12 Mart 2018 Pazartesi

range adaptors

Giriş
Genel kullanım için şu satırı dahil ederiz.
#include <boost/range/adaptors.hpp>
Kolay kullanım için şu satırı dahil ederiz.
using namespace boost::adaptors;
custom Adaptor
range adaptor'leri iterator ile dolaşmak için tasarlanmış. Eğer iterator aralığını vector'e çevirmek istersek kendi custom adaptor sınıfımızı yazmak gerekir. Şöyle yaparız.
struct make_vector_t
{
  template <class R>
  friend auto operator|(R&& range, make_vector_t)
  {
    using std::begin;
    using std::end;

    using value_type =
       typename iterator_traits<decltype(begin(range))>::value_type;
    return std::vector<value_type>(begin(range), end(range));
  }
} constexpr make_vector{};
Şöyle yaparız.
auto vs = v
    | transformed([](const MyStruct& c){return c.name();});
    | make_vector;
abs Sınıfı
Açıklaması şöyle.
A range adaptor for absolute values
Şöyle yaparız.
auto ans = boost::accumulate(
  boost::combine(X|differential|abs, Y|differential|abs),
    0ull,
    [](auto accum, auto const& xy) { return accum + std::max(boost::get<0>(xy),
                                                             boost::get<1>(xy)); }
);
adjacent_filtered Sınıfı
Örnek ver

copied Sınıfı
Örnek ver

differential Sınıfı
Açıklaması şöyle.
A range adaptor for adjacent_difference
filtered Sınıfı
filtered Sınıfı yazısına taşıdım.
indexed Sınıfı
Örnek ver

indirected Sınıfı
Örnek ver

map_keys Sınıfı
Şu satırı dahil ederiz.
#include <boost/range/adaptor/map.hpp>
Şöyle yaparız.
typedef std::map<std::string,valueInfo*> AssetMap ;

AssetMap map = ...;

using namespace boost::adaptors;
for (const auto & key : pList | boost::adaptors::map_keys  ) {
  std::cout << key << " ";

}
Şöyle yaparız.
std::unordered_map<std::string, int> map{{"one",1},{"two",2}};
for (auto& str : map | boost::adaptors::map_keys) {...}
Şöyle yaparız.
std::string get_keys (const std::map<std::string, std::string>& map) {
  return boost::algorithm::join(
    map | boost::adaptors::map_keys,
    ", ");
}
map_values Sınıfı
Şu satırı dahil ederiz.
#include <boost/range/adaptors.hpp>
Giriş
Aslında bu sınıfa C+11 ile gerek yok. Şöyle yaparız.
for (auto&& entry : map) {
  auto&& key = entry.first;
  auto&& value = entry.second.get();
  ...
}
Örnek
Şöyle yaparız.
foo(someMap | boost::adaptors::map_values);
Örnek
Elimizde şöyle bir map olsun.
struct valueInfo
{
  std::string val1;
  std::string val2;
  std::string val3;

};

typedef std::map<std::string,valueInfo*> AssetMap ;
Şöyle yaparız.
AssetMap map = ...;

using namespace boost::adaptors;
for (const auto & val : map | boost::adaptors::map_values) {
  std::cout << val->val1 << val->val2<< val->val3<< "\n";
}
replaced Sınıfı
Örnek ver

replaced_if Sınıfı
Örnek ver

reversed Sınıfı
Örnek
Şöyle yaparız.
std::vector<size_t> numbers = { 10, 11, 12, 13, 14, 2, 1, 3,3,50, 55} ;

if ( find(numbers|reversed,99) != (numbers|reversed).end() )
                                 //^adaptor chain repeated
{
    std::cout << "FOUND!!!!!" << std::endl;
}
Örnek
multi_map sınıfının equal_range() metodundan gelen bir iterator için şöyle yaparız.

auto const range = ...;

// traverse these in reverse
for (auto& el : range | boost::adaptors::reversed)
  std::cout << el.i << "," << el.name << "; ";
sliced Sınıfı
Giriş
Şu satırı dahil ederiz.
#include <boost/range/adaptor/sliced.hpp>
Constructor
Şöyle yaparız.
#include <boost/range/adaptor/sliced.hpp>
#include <vector>    
#include <iterator>

int main(int argc, char **argv) {
  vector<int> vec = {0,1,2,3,4,5,6,7,8,9,10};
  int from = 3;
  int to = 5;
  auto slice1 = vec | boost::adaptors::sliced(0, from);
  auto slice2 = vec | boost::adaptors::sliced(to, vec.size());
  ...
}
strided Sınıfı - Ayırarak dolaşmak
Şu satırı dahil ederiz.
#include <boost/range/adaptor/strided.hpp>
Şöyle yaparız. Her 2. elemanı siler yani kopyalamaz.
boost::copy(boost::make_iterator_range(in, in+size) |
  boost::adaptors::strided(2), out);
Şöyle yaparız.
int arr[] = {1, 2, 3, 4, 5, 6, 7};

auto str = std::make_pair(&arr[0], &arr[8]) | strided(3);
std::cout << *boost::range::min_element(str) << " " <<
          << *boost::range::max_element(str) << std::endl;
type_erased Sınıfı
Örnek ver

tokenized Sınıfı
Örnek ver

transformed Sınıfı
Şu satırı dahil ederiz.
#include <boost/range/adaptor/transformed.hpp>
Metod şu tipi döndürür. Bu tipi iterator ile dolaşabiliriz.
const boost::range_detail::transformed_range<...>
Örnek - std::mem_fun
Elimizde bir vector olsun
std::vector<std::string> v;
Şöyle yaparız.
auto vs =  v | boost::adaptors::transformed(std::mem_fn(&std::string::c_str));
Örnek - Sonucu parametre olarak geçme
Bu metod şöyle bir yapı döndürür.
using Range =
  boost::any_range<
    int,
    boost::forward_traversal_tag,
    const int,
    std::ptrdiff_t>;


std::vector<int> xs{0, 1, 2};

auto ys = xs | transformed([](auto x) { return x; });
Bu yapı ile sonucu başka bir metoda parametre olara verebiliriz. Şöyle yaparız.
void magic(const Range &) {}
Örnek - Sonucu Dolaşma
Elimizde bir struct olsun
struct MyStruct {
  explicit MyStruct(std::string name) : name_(name){}
  std::string name() const { return name_; }
private:
  std::string name_;
};


std::vector<MyStruct> vm;
vm.emplace_back("asd");
vm.emplace_back("qwe");
vm.emplace_back("zxc");
Şöyle yaparız.
using namespace boost::adaptors;
auto vs = vm | transformed([](const MyStruct& c){return c.name();});

for (const auto& c : vs)
  std::cout << c << std::endl;
Örnek - Sonucu Dolaşma
Şöyle yaparız.
std::unordered_map<std::string, int> map{{"one",1},{"two",2}};
for (char const* sz : map |
  transformed([](auto const& p) { return p.first.c_str(); }))
{
  std::cout << sz << "\n";
}
Örnek - Başka Veri Yapısını Doldurma
Şöyle yaparız.
const std::vector<int> vec = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

std::map<std::string, int > myMap; 
boost::copy(vec | boost::adaptors::transformed(alphabetize),
  std::inserter(myMap, myMap.end()));
Dönüşüm metodumuz bir pair döndürür. Şöyle yaparız.
std::pair<std::string, int> alphabetize(int i) 
{
  return std::make_pair(std::string(1, 'a' + i), i);
}
Örnek - Sıralama
Elimizde şöyle bir yapı olsun.
struct foo
{
  foo(std::string a) : bar(a) {}

  std::string bar;
  bool operator<(const foo& rhs) const {return bar < rhs.bar;}
};

std::vector<foo> words = { foo("z"), foo("d"), foo("b"), foo("c") };
Şöyle yaparız.
auto asString = boost::adaptors::transform(words,
  +[](const foo& x) {return x.bar;});
std::sort(asString.begin().base(), asString.end().base());
Şöyle yaparız.
auto asString = boost::adaptors::transform(words, 
  +[](foo& x) -> std::string& {return x.bar;});
uniqued Sınıfı
Örnek ver

Hiç yorum yok:

Yorum Gönder