16 Eylül 2019 Pazartesi

intrusive

list_base_hook Sınıfı
Giriş
Şu satırı dahil ederiz.
#include <boost/intrusive/list.hpp>
Bu sınıfın virtual destructor metodu yoktur ama sorun olmuyor. Açıklaması şöyle.
Deriving from boost::intrusive::list_base_hook<> is a totally valid design because ownership of derived objects is never held via a pointer to list_base_hook. Note that library offers hooking through aggregation (using  list_member_hook) which should be preferred to inheritance.
Bu sınıftan kalıtan nesneler boost::intrusive::list veriyapısına eklenir.

Tanımlama
Örnek
Şöyle yaparız.
struct MyStruct : public boost::intrusive::list_base_hook<>  {
  int i;
  MyStruct(const MyStruct &) = delete;
  MyStruct& operator= (const MyStruct &) = delete;
  MyStruct(int val) : i(val) {}
};
Örnek
Şöyle yaparız. nesne silinince otomatik olarak listeden de silinir.
struct X : public bi::list_base_hook<bi::link_mode<bi::auto_unlink> > {
  X(int a_in) : a{a_in} {}
  int a;
};

std::vector<X> vec { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
bi::list<X, bi::constant_time_size<false> > list(vec.begin(), vec.end());
unlink metodu
Şöyle yaparız.
using namespace boost::intrusive;

typedef list_base_hook<link_mode<auto_unlink> > auto_unlink_hook;

class Foo : public auto_unlink_hook
{
  int int_;
public:
  Foo(int i = 0)   :  int_(i)  {}
  int  get_int()    { return int_; }
  void unlink()     {  auto_unlink_hook::unlink(); }
  bool is_linked()  {  return auto_unlink_hook::is_linked();  }
};
list Sınıfı
Tanımlama
Şöyle yaparız.
boost::intrusive::list<MyStruct> list;
Constructor - iterator + iterator
Şöyle yaparız.
struct X : public boost::intrusive::list_base_hook<> {
  X(int a_in) : a{a_in} {}
  int a;

  friend std::ostream& operator<<(std::ostream& os, X const& x) {
    return os << "{" << x.a << "}"; 
  }
};

std::vector<X> vec { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
boost::intrusive::list<X> list(vec.begin(), vec.end());
erase metodu
Elimizde daha önce listeye eklediğimiz yapı olsun.
MyStruct* p = ...;
Şöyle yaparız.
l.erase(boost::intrusive::list<MyStruct>::s_iterator_to(*p));
Daha kolay bir yöntem olarak şöyle yaparız.
p->unlink();
push_back metodu
Şöyle yaparız.
MyStruct a(1);
list.push_back(a);
remove_if metodu
Şöyle yaparız.
struct X : public boost::intrusive::list_base_hook<> {
  X(int a_in) : a{a_in} {}
  int a;

  friend std::ostream& operator<<(std::ostream& os, X const& x) {
    return os << "{" << x.a << "}"; 
  }
};

std::ostream_iterator<X> out(std::cout << std::unitbuf, " ");

std::vector<X> vec { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
boost::intrusive::list<X> list(vec.begin(), vec.end());

std::cout << "before: "; std::copy(list.begin(), list.end(), out);

list.remove_if([](X const& x) { return 0 == (x.a % 2); });

std::cout << "\nafter: "; std::copy(list.begin(), list.end(), out);
Çıktı olarak şunu alırız.
before: {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} 
after: {1} {3} {5} {7} {9} 
s_iterator_to metodu
Şöyle yaparız.
using namespace boost::intrusive;

typedef list_base_hook<link_mode<auto_unlink> > auto_unlink_hook;

class Foo : public auto_unlink_hook
{
    int int_;
    public:
    Foo(int i = 0)   :  int_(i)  {}
    int  get_int()    { return int_; }
    void unlink()     {  auto_unlink_hook::unlink(); }
    bool is_linked()  {  return auto_unlink_hook::is_linked();  }
};


typedef list<Foo, constant_time_size<false>> ListType;
ListType l;
Foo foo1{42};
l.push_back(foo1);

auto itr1 = ListType::s_iterator_to(foo1);
instrusive_ref_ctr Sınıfı
Örnek
Şöyle yaparız.
include <iostream>
#include <boost/intrusive_ptr.hpp>
#include <boost/smart_ptr/intrusive_ref_counter.hpp>

class C : public boost::intrusive_ref_counter<C, boost::thread_safe_counter> {
public:
  static void* operator new(size_t size) {
    void* p = ::operator new(size);
    std::cout << "C::new() -> " << p << "\n";
    return p;
  }

  static void operator delete(void* p) {
    std::cout << "C::delete() -> " << p << "\n";
    ::operator delete(p);
  }
};

int main() {
    boost::intrusive_ptr<C> c(new C);
}
intrusive_ptr Sınıfı
Şu satırı dahil ederiz.
#include <boost/intrusive_ptr.hpp>
Constructor
Şöyle yaparız.
boost::intrusive_ptr<event_two> ptr (new event_two);
Gerekli Alanlar
Açıklaması şöyle.
The class must have the reference counter as one of its members or derive from boost::intrusive_ref_counter.
Şu alanın tanımlanması gerekir.
template<typename T> class list {
  class node {
    std::size_t mutable refcount_;
    ...
  };

  boost::intrusive_ptr<node> node_{new node};
};
Gerekli Metodlar
Şu metodların gerçekleşmesi gerekir. Açıklaması şöyle
"Every new intrusive_ptr instance increments the reference count by using an unqualified call to the function intrusive_ptr_add_ref, passing it the pointer as an argument. Similarly, when an intrusive_ptr is destroyed, it calls intrusive_ptr_release; this function is responsible for destroying the object when its reference count drops to zero. The user is expected to provide suitable definitions of these two functions. "
Açıklaması şöyle. Tüm modern derleyiciler ADL'i destekliyor.
On compilers that support argument-dependent lookup, intrusive_ptr_add_ref and intrusive_ptr_release should be defined in the namespace that corresponds to their parameter; otherwise, the definitions need to go in namespace boost.
intrusive_ptr_add_ref metodu
Şöyle yaparız.
// friends of list because accessing private nested class node
friend void intrusive_ptr_add_ref(node const* p) noexcept {
  p->refcount_ += 1;
}
intrusive_ptr_release metodu
Şöyle yaparız.
friend void intrusive_ptr_release(node const* p) noexcept {
  if (--p->refcount_)
    return;
  std::cout << "freeing node " << static_cast<void const*>(p) << "\n";
}
set Sınıfı
Giriş
Şu satırı dahil ederiz.
#include <boost/intrusive/set.hpp>
Tanımlama
Elimizde bir struct olsun
/// vertex properties
struct VertexData : bi::set_base_hook<bi::link_mode<bi::auto_unlink>,
  bi::constant_time_size<false> > {
  std::string label;
  int num;

  VertexData(std::string label, int num) : label(label), num(num) {}

  struct by_label {
    using type = std::string;
    std::string const& operator()(VertexData const& vd) const { return vd.label; }
  };
};
Şöyle yaparız
using by_label_idx_t = bi::set<VertexData, bi::constant_time_size<false>,
  bi::key_of_value<VertexData::by_label> >;
Constructor
Şöyle yaparız.
by_label_idx_t myset;
clear metodu
Şöyle yaparız.
myset.clear();
insert metodu
Şöyle yaparız.
myset.insert(...);
slist Sınıfı
Tanımlama
Şöyle yaparız.
struct Entry : public boost::intrusive::slist_base_hook<> {
  int num;
};

typedef boost::intrusive::slist<
  Entry, boost::intrusive::cache_last<true> > Point;
unordered_set Sınıfı
Tanımlama
Şöyle yaparız.
using namespace boost::intrusive;

typedef unordered_set_member_hook<> Hook;

struct Item
{
  Hook hook;
};

typedef unordered_set<Item,
    member_hook<Item, Hook, &Item::hook>,
    size_type<uint32_t> > Map;


Hiç yorum yok:

Yorum Gönder