7 Aralık 2020 Pazartesi

BOOST_ASSERT Macrosu

Giriş
Bu macro genelde şöyle kullanılır
BOOST_ASSERT(!!p); // where `p` is a pointer
Açıklaması şöyle
By default, BOOST_ASSERT(expr) expands to assert(expr). That C++ assert function takes a scalar argument, not bool. Thus, your statement, "the expected expression is a boolean," is not correct.

Classes in C++ can implement operator bool(); the basic_stream classes are examples of such: assert(std::cin) will not work. The !! operator forces the use of std::cin::operator bool(), and bool after !! will be evaluated to int 0 or 1. This is shorter than assert(bool(std::cin)).

19 Temmuz 2020 Pazar

sort pdqsort_branchless

Giriş
quick sort gibidir. Açıklaması şöyle
Boost's quicksort and the STL's std::sort are very close together in runtime performance.
Örnek
Şöyle yaparız
#include <boost/sort/pdqsort/pdqsort.hpp>

using namespace boost::sort; 

vector<int> arr = ...;
pdqsort_branchless(arr.begin(), arr.end(),[](const int &a, const int &b){return (a<b);});

28 Haziran 2020 Pazar

serialization BOOST_STRONG_TYPEDEF

Giriş
Şu satırı dahil ederiz.
#include <boost/serialization/strong_typedef.hpp>
Bu macro niçin serialization altında bilmiyorum. Amacı mevcut bir tipten yepyeni bir tip tanımlayabilmek. Bu yepyeni tip, metod parametrelerinde kullanılarak daha type safe bir kod elde ediliyor.

1. Rust Dili
Benzer bir özellik Rust programlama dilinde var. O da bu özelliği Haskell'den almış deniliyor.
Örnek
Rust dilinde şöyle yaparız. old_enough() metodu sadece Years tipi ile çağrılabilir. i64 olan bir başka parametre ile çağrılamaz.
struct Days(i64);
struct Years(i64);

fn old_enough(age: &Years) -> bool {
    age.0 >= 18
}
2. typdef Kelimesi Farklı Tipler Yaratmak İçin Yetersizdir
Örnek
İşe yaramadığını görmek için şöyle yaparız. Elimizde şöyle bir kod olsun.
typedef int TA;
typedef int TB;
std::variant<TA, TB> a(TA(1));
Bu kod içinde TA ve TB isminde iki farklı tip yaratılıyor gibi görünse de derleyici bunları farklı şeyler olarak düşünmeyebilir. Bu yüzden BOOST_STRONG_TYPEDEF kullanımına ihtiyacımız var.

3. using Kelimesi Farklı Tipler Yaratmak İçin Yetersizdir
Örnek
İşe yaramadığını görmek için şöyle yaparız
typedef int Days;
using Years = int;

bool old_enough(Years age) {
  return age >= 18;
}
4. Alternatif Çözümler
Eğer elimizdeki tip primitive ise enum kullanılabilir. Ancak primitive değilse bu çözüm işe yaramaz.

Örnek
Şöyle yaparız
enum class Days : int {};
enum class Years : int {};

bool old_enough(Years age) {
  return static_cast<int>(age) >= 18;
}
5. Eğer Kendimiz Gerçekleştirmek İstersek
Açıklaması şöyle. Template sınıfın ilk parametresini Tag yaparız.
...another common approach is making(/expanding) the Number class (template) a class template parameterized over type template tag parameter, such that specializations over the tag types results in strong typing.
Örnek
Şöyle yaparız.
template<typename Tag, typename ValueType = int>
struct Number {
  ValueType value;
  // ... common number functionality.
};

using YearNumber = Number<struct NumberTag>;
using DayNumber = Number<struct DayTag>;

void takeYears(const YearNumber&) {}
void takeDays(const DayNumber&) {}

int main() {
  YearNumber y{2020};
  DayNumber d{5};
    
  takeYears(y);
  //takeDays(y);  // error: candidate function not viable
    
  takeDays(d);
  //takeYears(d);  // error: candidate function not viable
    
  return 0;
}
6. BOOST_STRONG_TYPEDEF Kullanımı
Ve nihayet bu macronun kullanımına bakalım.

Örnek
Şöyle yaparız. TIMER_ID ve PROCESS_ID string olmalarına rağmen == kodu derleme hatası verir.
BOOST_STRONG_TYPEDEF(std::string, TIMER_ID)
BOOST_STRONG_TYPEDEF(std::string, PROCESS_ID)

int main()
{
  TIMER_ID t_id("Timer");
  PROCESS_ID p_id("Process");

  if (t_id == p_id)
    std::cout << "They are equal!" << std::endl;
}
Örnek
Şöyle yaparız.
BOOST_STRONG_TYPEDEF(int, X)
BOOST_STRONG_TYPEDEF(int, Y)
BOOST_STRONG_TYPEDEF(int, Width)
BOOST_STRONG_TYPEDEF(int, Height)

struct Rect {
  Rect(X x, Y y, Width w, Height h);
};

// Usage:
Rect rect(X(10), Y(20), Width(800), Height(600));
Örnek
Elimizde şöyle bir typedef olsun
BOOST_STRONG_TYPEDEF(std::string, MY_ID)
Şöyle yaparız.
std::vector<std::string> id_vec = ...;

std::set<MY_ID> ids;
for (auto const & id : id_vec)
{
  ids.insert(MY_ID{id});
}