29 Nisan 2016 Cuma

std::default_random_engine - Bir Pseudo-random number generator (PRNG)

Giriş
Şu satırı dahil ederiz.
#include<random>
C++ kütüphanesinin gerçekleştirimine bırakılmış. Açıklaması şöyle
Remark: The choice of engine type named by this typedef is implementation-defined. [ Note: The implementation may select this type on the basis of performance, size, quality, or any combination of such factors, so as to provide at least acceptable engine behavior for relatively casual, inexpert, and/or lightweight use. Because different implementations may select different underlying engine types, code that uses this typedef need not generate identical sequences across implementations. — end note ]
Bence bu sınıfı kullanmamak gerekir. Bu sınıf GCC'de minstd_rand0 olarak gerçekleştirilmiş.
VS2012'de ise mt19937 olarak gerçekleştirilmiş .

constructor - default
Sınıfı şöyle yaratabiliriz. Ancak bu durumda seed vermediğimiz için hep aynı sonuçları elde ederiz.
std::default_random_engine generator;
constructor - time
Sistem saatini kullanarak şöyle yaparız.
std::default_random_engine generator( (unsigned int)time(0) );
constructor - chrono time
Chrono kullanarak şöyle yaparız.
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::default_random_engine generator (seed));
constructor - random_device
Donanım tabanlı bir üreteci kullanarak şöyle yaparız.
std::default_random_engine generator( std::random_device{}() ); 




20 Nisan 2016 Çarşamba

std::atexit

Giriş
atexit main metod içinden return ile çıkılınca veya exit() metodu çağırılınca işletilen bir metodları eklemek için kullanılır

POSIX standardında pthread_cleanup_push() herhangi bir thread'den çıkınca işlem yapmak için kullanılır.

Şöyle yaparız.
#include <iostream>
#include <cstdlib>

void atexit_handler_1() 
{
    std::cout << "at exit #1\n";
}

void atexit_handler_2() 
{
    std::cout << "at exit #2\n";
}

int main() 
{
    const int result_1 = std::atexit(atexit_handler_1);
    const int result_2 = std::atexit(atexit_handler_2);

    if ((result_1 != 0) or (result_2 != 0)) {
        std::cerr << "Registration failed\n";
        return EXIT_FAILURE;
    }

    std::cout << "returning from main\n";
    return EXIT_SUCCESS;
}


19 Nisan 2016 Salı

std::get_money

Giriş
Şu satırı dahil ederiz.
#include <locale>
std::get_money metodu
Elimizde şöyle bir satır olsun.
$89.99
Bu satırı okumak için şöyle yaparız. Doldurulan parametre long double veya string olmalıdır. Değerin kuruş biriminde olduğu varsayalır.
long double price;   get_money only supports long double
ifstream filein("bookfile.txt");

filein.imbue(std::locale("en_US.UTF-8"));
filein >> std::get_money(price);
price /= 100;  //get_money uses the lowest denomination, in this case cents


15 Nisan 2016 Cuma

std::mutex Sınıfı

Giriş
Yeni mutex tipleri şunlar. Bu tipler POSIX'teki mutex tipleri ile aynı.

std::mutex, std::timed_mutex (C++11)
std::recursive_mutex, std::timed_recursive_mutex (C++11)
std::shared_mutex (C++17) , std::shared_timed_mutex (C++14)

Mutex Lockable kavramını getirir.

Mutex temel olarak şu metodları sunar.
  • lock
  • unlock
  • try_lock
Windows'ta std::mutex
std::mutex Windows'ta altta CriticalSection ile gerçekleştirilmiş. Mutex içinde şöyle bir kod var.
struct _Mtx_internal_imp_t
{   /* Win32 mutex */
    int type; // here MS keeps particular mutex type
    Concurrency::critical_section cs;
    long thread_id;
    int count;
};
Aslında ne ile gerçekleştirilmiş olduğunun pek bir önemi yok. CriticalSection ve std::mutex farklı şeyler. CriticalSection aynı thread tarafından birden fazla kilitlenebilir. Yani recursive bir yapıdır. std::mutex ise sadece bir kere kilitlenebilir.

try_lock metodu
Bu metodu hiç bir zaman kullanmamak en iyisi. unique_lock kullanmak en güzel çözüm.
unique_lock( mutex_type& m, std::try_to_lock_t t );
Şöyle kullanılırsa çok fazla işlemci yer.
std::mutex m;
while (!m.try_lock()) {}
# do work
m.unlock();



1 Nisan 2016 Cuma

locale ve karakterler

Giriş
Şu satırı dahil ederiz.
#include <cctype>
Bu metodlar seçili locale ile çalışır. Eğer belirtilen bir locale ile çalışmak istersek std::ctype facet kullanılır.

Küme Metodları
isalphanum metodu
Şöyle yaparız.
if (isalphanum(chValue)){...}
isblank metodu
Şöyle yaparız.
if (isblank(chValue)){...}
isupper metodu
isupper metodu verilen karakterin büyük olup olmadığını döndürür. Normalde ASCII kullandığımız için kod çok kolaydır ancak locale işin içine girince farklı kodlar yazmak gerekir. Örneğin EBCDIC için kod şöyle bir hal alır.
inline int is_upper_alpha(char chValue)
{
    if (((chValue >= 'A') && (chValue <= 'I')) ||
        ((chValue >= 'J') && (chValue <= 'R')) ||
        ((chValue >= 'S') && (chValue <= 'Z')))
        return 1;
    return 0;
}
ASCII için şöyle olmalıydı
inline int is_upper_alpha(char chValue)
{
    return ((chValue >= 'A') && (chValue <= 'Z'));
}
Bir de locale işin içine girince ortalık daha da karışır. Bu yüzden isupper() metod altta ctype nesnesini kullanarak bizi bu zahmetten kurtarır.

Dönüşüm Metodları
tolower
Metodun imzası şöyle
int std::tolower(int ch); // #include <cctype>
Metoda geçilen parametre unsigned char olarak geçilmeli.
for (char &ch : mystr)
    ch = std::tolower( (unsigned char)ch );
Neden var bilmiyorum ancak locale dosyası içinde de aynı isme ancak farklı imzaya sahip bir metod daha var.
template<typename charT>
charT std::tolower(charT ch, const std::locale& loc);    // #include <locale>