9 Aralık 2019 Pazartesi

hana

Giriş
Şu satırı dahil ederiz.
#include <boost/hana.hpp>
Kolay kullanım için şu satırı dahil ederiz.
namespace hana = boost::hana;
using namespace hana::literals;
BOOST_HANA_DEFINE_STRUCT
Şu satırı dahil ederiz.
#include <boost/hana/define_struct.hpp>
Introspection için kullanılır.
Örnek
Şöyle yaparız.
struct Person {
  BOOST_HANA_DEFINE_STRUCT(Person,
    (std::string, name),
    (unsigned short, age)
  );
};
Örnek
std::array için şöyle yaparız.
struct Person {
  BOOST_HANA_DEFINE_STRUCT(Person,
    (std::array<float,2>, eye_dioptre)
  );
C tarzı array için şöyle yaparız.
template<size_t N>
using floatArr = float[N];
Daha sonra şöyle yaparız.
struct Test {
    BOOST_HANA_DEFINE_STRUCT(Test,
        (floatArr<2>, example)
    );
};
any_of metodu
Şöyle yaparız. any_of metodunun nerede duracağı belli değil.
auto t = boost::hana::tuple_t<int, double, float>;
boost::hana::any_of(t, [](auto) { std::cout << "Called\n"; return true; });
Çıktı olarak şunu alırız.
Called
Called
at_key metodu
Şöyle yaparız.
#include <iostream>
#include <vector>
#include <boost/hana.hpp>

struct Boundary {
  BOOST_HANA_DEFINE_STRUCT(Boundary,
      (int, top),
      (int, left),
      (int, bottom),
      (int, right)
  );
};

template<class C, class Name>
int make_sum(C const& c, Name name) {
    int sum = 0;
    for(auto const& elem : c) {
        auto& member = boost::hana::at_key(elem, name);
        sum += member;
    }
    return sum;
}

int main() {
    std::vector<Boundary> v{{0,0,1,1}, {1,1,2,2}};

    std::cout << make_sum(v, BOOST_HANA_STRING("top")) << '\n';
    std::cout << make_sum(v, BOOST_HANA_STRING("bottom")) << '\n';
}
filter metodu
Açıklaması şöyle
A function called as predicate(k), where k is a key of the structure, and returning whether k is the key of the element being searched for. In the current version of the library, the predicate has to return an IntegralConstant holding a value that can be converted to bool.
Şöyle yaparız.
hana::filter (hana::tuple_t<int, foo>, [](auto type) {
  return ...;
});
find_if metodu
Açıklaması şöyle
A function called as predicate(k), where k is a key of the structure, and returning whether k is the key of the element being searched for. In the current version of the library, the predicate has to return an IntegralConstant holding a value that can be converted to bool.
Şöyle yaparız
auto default_ = hana::find_if(cases, [](auto const& c) {
  return hana::first(c) == hana::type_c<default_t>;
});
static_assert(default_ != hana::nothing, "switch is missing a default_ case");
Şöyle yaparız.
auto found = hana::find_if(rest, [&](auto const& c) {
  using T = int; // typename decltype(+hana::first(c))::type;
  return hana::bool_c<typeid(int) == type_idx>;
  // return hana::bool_c<false>;
});
if constexpr (found == hana::nothing) {
  return hana::second(*default_)();
}
else {
  using T = typename decltype(+hana::first(*found))::type;
  return hana::second(*found)(*boost::unsafe_any_cast<T>(&a));
}
for_each metodu
Bir struct'ın tüm alanlarını dolaşmak için kullanılır.
Örnek
Macrolar kullanan bir örnek şöyle.
Örnek
şöyle yaparız.
template <typename S>
void debug_print(const S & s) {
  
  hana::for_each(hana::keys(s), [&s] (auto key) {
    ...
  });
}
Örnek
Şöyle yaparız.
struct Car {
  BOOST_HANA_DEFINE_STRUCT(Car,
    (std::string, brand),
    (std::string, model),
    (std::array<char, 4>, year)
  );
};

Car bmw{"BMW", "Z3", {'2', '0', '1', '0'}};


hana::for_each(hana::accessors<Car>(), [&](auto pair)
{
  ...
});

int_ Sınıfı
Şöyle yaparız.
hana::transform(vals, [](auto x){ return hana::int_c<1> << x; });
make_map metodu
Örnek
Şöyle yaparız.
auto expected = hana::make_map(
    hana::make_pair(hana::type_c< int >, false),
    hana::make_pair(hana::type_c< float >, false)
  );
Örnek
Elimizde bir Foo sınıfı olsun.
template <typename T>
class Foo {
  T t;

  public:
    void print() { std::cout << typeid(T).name() << "t\n"; }
};
map oluşturmak için şöyle yaparız.
namespace detail {
  template <typename... T>
  static inline auto make_foo_map() {
    return boost::hana::unpack(hana::tuple_t<T...>, [](auto... t) {
      return boost::hana::make_map(boost::hana::make_pair(t,
        Foo<typename decltype(t)::type>())...);
    });
  }
}

template <typename... T>
using FooMap = decltype(detail::make_foo_map<T...>());
Şöyle yaparız.
FooMap<float, int, std::string> my_map;

my_map[hana::type_c<int>].print();
my_map[hana::type_c<float>].print();
my_map[hana::type_c<std::string>].print();
make_range metodu
Şöyle yaparız.
auto indices = hana::make_range (0_c, hana::length(handlers));
hana::for_each(indices, [&](auto i) {
  ...
});
make_set metodu
Şöyle yaparız.
auto my_set = hana::make_set(hana::type_c< int >, hana::type_c< float >);
make_tuple metodu
Şöyle yaparız.
auto tuple1 = hana::make_tuple(Foo{}, Bar{});
Şöyle yaparız.
auto tuple2 = hana::make_tuple(5, -12);
Sequence
Açıkaması şöyle
A hana::Sequence is supposed to be able to hold arbitrary things, not only types.

transform metodu
Örnek 1
Elimizde bir tuple olsun. Tuple'daki tipleri hana::tuppe<std::vector<...>>'e doldurmak istersek şöyle yaparız.
auto types = hana::tuple_t<A,B,C>;
auto vecs = hana::transform(types, [](auto t) {
    return hana::type_c<std::vector<typename decltype(t)::type>>;
});    

static_assert(vecs == 
              hana::tuple_t<std::vector<A>, std::vector<B>, std::vector<C>>, 
              "wat");
Örnek 2
Elimizde şöyle bir metod olsun.
template <int X>
constexpr auto Pow2(hana::int_<X>) { return hana::int_c<1 << X>; }
Şöyle yaparız.
constexpr auto vals = hana::to<hana::tuple_tag>(hana::range_c<int, 0, 3>);
constexpr auto res = hana::transform(vals, [](auto x){ return Pow2(x); });

static_assert(std::is_same_v<
    std::decay_t<decltype(res)>,
    hana::tuple<hana::int_<1>, hana::int_<2>, hana::int_<4>>
>);
tuple Sınıfı
Şu satırı dahil ederiz.
#include <boost/hana/tuple.hpp>
Şöyle yaparız.
boost::hana::tuple<A, B> names;
boost::hana::for_each(names, [&](const auto& x) {
    std::cout << x.name << std::endl;
});
tuple_t Sınıfı
Şöyle yaparız.
constexpr auto types = hana::tuple_t<int, char, double, float>;
zip metodu
İki tane tuple'ı birleştirmek için şöyle yaparız.
auto tuple1 = ...;
auto tuple2 = ...;
auto zip = hana::zip (tuple1, tuple2);
Bu nesne şöyle dolaşılır.
hana::for_each(zip, [](auto &element) {
  element [0_c] (element[1_c]);
});
Bu nesne şöyle dönüştürülür.
auto result = hana::transform (zip, [](const auto &element) {
  return element [1_c];
});