Monday, September 25, 2017

C++14: The attribute [[deprecated]] Attribute

C++14 added the [[deprecated]] attribute to mark functions in the code as being deprecated. Here is an example:

[[deprecated]]
/////////////////////////////////////////////////
void f()
{

}

[[deprecated("My additional message.")]]
void g()
{

}

int main()
{
  f();
  g();
  return 0;
}
// Compiler Output: warning C4996: 'f': was declared deprecated
//                  warning C4996: 'g': My additional message.
Reference: https://en.wikipedia.org/wiki/C%2B%2B14#The_attribute_.5B.5Bdeprecated.5D.5D

C++14: Lambda capture expressions

C++14 added lambda capture expressions, which are mainly used to allow moves in lambda function parameters. Here is an example:

#include <iostream>
#include <memory>
#include <utility>

int main()
{
  std::unique_ptr<int> pInt{new int(9)};

  std::cout << pInt.get() << " ";

  auto myLambda = [lambda_ptr = std::move(pInt)]()
                  {
                    std::cout << lambda_ptr.get() << " ";
                  };

  myLambda();

  std::cout << pInt.get() << " ";

  std::cout << std::endl;
  return 0;
}
// Output: 003B9E90 003B9E90 00000000
Reference: https://en.wikipedia.org/wiki/C%2B%2B14#Lambda_capture_expressions

C++14: Generic lambdas

C++14 added generic lambdas. Here is an example:

#include <iostream>
#include <string>

auto myLambda = [](auto x, auto y) {return x + y;};

int main()
{
  std::cout << myLambda(3, 4) << " ";
  std::cout << myLambda(std::string("Hello"), std:: string("World")) << " ";
  std::cout << myLambda(3.3, 4.4) << " ";

  std::cout << std::endl;
  return 0;
}
// Output: 7 HelloWorld 7.7
Reference: https://en.wikipedia.org/wiki/C%2B%2B14#Generic_lambdas

C++14: Digit separators

C++14 added digit separators (single apostrophes) that can be used to make literals easier to read. Here is an example:

#include <iostream>

int main()
{
  std::cout << std::hex << 0b1111'1010'1111'1010 << " ";
  std::cout << std::hex << 0x0123'4567'89ab'cdef << " ";
  std::cout << std::dec;
  std::cout << 123'456'789 << " ";
  std::cout << 123'456.0   << " ";
  std::cout << 9.012'345   << " ";
  std::cout << std::endl;
  return 0;
}
// Output: fafa 123456789abcdef 123456789 123456 9.01234
Reference: https://en.wikipedia.org/wiki/C%2B%2B14#Digit_separators

C++14: Binary literals

C++14 added ‘0b’ and ‘0B’ to be a literal prefix that specifies the literal represents a binary number. Here is an example:

#include <iostream>

int main()
{
  int i = 0b0;
  std::cout << 0b0 << " ";
  std::cout << 0B0 << " ";
  std::cout << 0b1010 << " ";
  std::cout << 0b00001010 << " ";
  std::cout << std::hex << 0b00001010 << " ";
  std::cout << std::hex << 0b1111101011111010 << " ";
  std::cout << std::hex << 0b11111010111110101111101011111010 << " ";
  std::cout << std::hex <<
   0b1111101011111010111110101111101011111010111110101111101011111010
    << " ";

  std::cout << std::endl;
}
/// Output: 0 0 10 10 a fafa fafafafa fafafafafafafafa
Reference: https://en.wikipedia.org/wiki/C%2B%2B14#Binary_literals

C++14: Aggregate member initialization

C++14 allows ‘initializer lists’ also to be used on classes and structs that have ‘member initializers’. Missing values from the ‘initializer list’ will be taken from the ’member initializer.’ It does not work on either VS2014 or gcc version 4.9.3 20150428. Here is an example:

#include <iostream>

struct A
{
  int mVar1 = 1; // '= 1' is a member initializer.
  int mVar2 = 2; // '= 2' is a member initializer.
  int mVar3 = 3; // '= 3' is a member initializer.
};

int main()
{
     A a1;
  // A a2{91, 92, 93}; // '{91, 92, 93}' is an initializer list.
  //                      This should work for C++14, but does not
  //                      work for either VS2014 or 
  //                      gcc version 4.9.3 20150428.
     A a3{ };

     std::cout << a1.mVar1 << " " << a1.mVar2 << " " << a1.mVar3 << " ";
  // std::cout << a2.mVar1 << " " << a2.mVar2 << " " << a2.mVar3 << " ";
     std::cout << a3.mVar1 << " " << a3.mVar2 << " " << a3.mVar3 << " ";
     std::cout << std::endl;
  return 0;
}
// Output: 1 2 3 1 2 3
Reference: https://en.wikipedia.org/wiki/C%2B%2B14#Aggregate_member_initialization

C++14: Variable templates

C++14 allows variables to be templated. Here is an example:

#include <iostream>

template<typename T>
constexpr T npos = T(-1); 

int main()
{
  std::cout << npos<         double   > << " ";
  std::cout << npos<         long long> << " ";
  std::cout << npos<         int      > << " ";
  std::cout << npos<         short    > << " ";
  std::cout << npos<unsigned long long> << " ";
  std::cout << npos<unsigned int      > << " ";
  std::cout << npos<unsigned short    > << " ";
  std::cout << std::endl;
  return 0;
}
// Output: -1 -1 -1 -1 18446744073709551615 4294967295 65535
Reference: https://en.wikipedia.org/wiki/C%2B%2B14#Variable_templates

C++14: Relaxed constexpr restrictions

C++14 allows more cases where a function can be declared constexpr. This includes any function satisfies the following 
criteria:
  1. It contains only variable declarations not declared static nor thread_local.
  2. It contains no variable declarations without initializers.
The function can contain if, switch, and loop statements.
The function can change the values of objects, as long as those object is during the execution of the function.

C++14: Alternate type deduction on declaration

C++14 added the combined decltype(auto) in order to be able to deduce a reference type. Here is an example:

#include <iostream>
 
int main()
{
  int              lvalue  = 4     ;
  int            & rvalue  = lvalue;
  auto             lvalue2 = rvalue;
  decltype(auto)   rvalue2 = rvalue;
 
  std::cout << (&lvalue == &rvalue ) << " ";
  std::cout << (&lvalue == &rvalue2) << " ";
  std::cout << (&lvalue == &lvalue2) << " ";
  std::cout << std::endl;
 
  return 0;
}
// Output: 1 1 0
Reference: https://en.wikipedia.org/wiki/C%2B%2B14#Alternate_type_deduction_on_declaration.5B5.5D

C++14: Deduced Return Type

C++14 allows all functions to deduce the return type. C++11 only allowed lambda functions to do this. Here is an example:

auto myFunction()
{
  return 1;
}

int main()
{
  int i = myFunction();

  return 0;
}
Reference: https://en.wikipedia.org/wiki/C%2B%2B14#Function_return_type_deduction

Monday, September 18, 2017

C++11: recursive_mutex

C++11 added a timed_mutex template class that allows you to recursively obtain a lock by a single thread. Here is an example:

#include <iostream>
#include <mutex>
#include <thread>

int gSharedData[2] = {1, 1};
std::recursive_mutex gRecursiveMutex;

void updateData()
{
  gRecursiveMutex.lock();
  gSharedData[0] = gSharedData[0] + 1;
  gRecursiveMutex.lock();
  gSharedData[1] = gSharedData[1] + 1;
  gRecursiveMutex.lock();
  std::cout << gSharedData[0] << " " << gSharedData[1] << " ";
  gRecursiveMutex.unlock();
  gRecursiveMutex.unlock();
  gRecursiveMutex.unlock();
}

struct FunctionClass
{
  void operator()()
  {
    int temp = 0;
    for (int i = 0; i < 3; i++)
    {
      updateData();
    }
  }
};

int main()
{
  std::thread t1{FunctionClass()};
  std::thread t2{FunctionClass()};
  std::thread t3{FunctionClass()};

  t1.join();
  t2.join();
  t3.join();
  std::cout << std::endl;
  return 0;
}
// Output: 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10



C++11: try_lock_until

C++11 added a timed_mutex template class that allows you to try for a lock until a specific point in time. Here is an example:

#include <iostream>
#include <mutex>
#include <thread>

std::timed_mutex gTimedMutex;

int main()
{
  if (gTimedMutex.try_lock_for(std::chrono::milliseconds(100)))
  {
    std::cout << "got_lock ";
  }
  else
  {
    std::cout << "try_lock_timeout ";
  }
  if (gTimedMutex.try_lock_for(std::chrono::milliseconds(100)))
  {
    std::cout << "got_lock ";
  }
  else
  {
    std::cout << "try_lock_timeout ";
  }
  gTimedMutex.unlock();
  if (gTimedMutex.try_lock_for(std::chrono::milliseconds(100)))
  {
    std::cout << "got_lock ";
  }
  else
  {
    std::cout << "try_lock_timeout ";
  }

  std::cout << std::endl;
  return 0;
}
// Output: got_lock try_lock_timeout got_lock



C++11: timed_mutex: try_lock_for

C++11 added a timed_mutex template class that allows you to try for a lock for a specified period of time. Here is an example:

#include <iostream>
#include <mutex>
#include <thread>
 
std::timed_mutex gTimedMutex;
 
int main()
{
  if (gTimedMutex.try_lock_for(std::chrono::milliseconds(100)))
  {
    std::cout << "got_lock ";
  }
  else
  {
    std::cout << "try_lock_timeout ";
  }
  if (gTimedMutex.try_lock_for(std::chrono::milliseconds(100)))
  {
    std::cout << "got_lock ";
  }
  else
  {
    std::cout << "try_lock_timeout ";
  }
  gTimedMutex.unlock();
  if (gTimedMutex.try_lock_for(std::chrono::milliseconds(100)))
  {
    std::cout << "got_lock ";
  }
  else
  {
    std::cout << "try_lock_timeout ";
  }
 
  std::cout << std::endl;
  return 0;
}
// Output: got_lock try_lock_timeout got_lock




C++11: At_Quick_Exit

C++11 added the function at_quick_exit to register functions that are called when quick_exit is called, after of which the process ends. Here is an example:

#include <cstdlib>
#include <iostream>

void f1() {std::cout << "f1 called: ";}
void f2() {std::cout << "f2 called: ";}
void f3() {std::cout << "f3 called: ";}

int main()
{
  at_quick_exit(f1);
  at_quick_exit(f2);
  at_quick_exit(f3);
  quick_exit(EXIT_SUCCESS);
  return 0;
}
// Output: f3 called: f2 called: f1 called:
Reference: http://www.cplusplus.com/reference/cstdlib/quick_exit/

C++11: Async

C++11 added the template function async that runs a function asynchronously. Here is an example:

#include <chrono>
#include <future>
#include <iostream>
#include <string>
#include <thread>

class FunctionClass
{
 private:
  std::string mThreadName;
  int         mSleepTime;
  
 public:
  int operator()()
  {
    std::this_thread::sleep_for(
                        std::chrono::milliseconds(mSleepTime));
    for (int i = 0; i < 3; i++)
    {
      std::cout << mThreadName;
    }
    std::cout << " ";
    return mSleepTime + 1000;
  }
  FunctionClass(std::string threadName, int sleepTime)
  : mThreadName(threadName), mSleepTime(sleepTime)
  {}
};

int main()
{
  FunctionClass f1("F1", 200);

  auto handle = std::async(std::launch::async, f1);

  std::cout << handle.get() << std::endl;

  return 0;
}
// Output: F1F1F1 1200
Reference: http://en.cppreference.com/w/cpp/thread/async

C++11: Promise

C++11 added template class std::promise that enables a thread to store a value or exception that can be accessed by another thread. Here is an example:

#include <chrono>
#include <future>
#include <iostream>
#include <string>
#include <thread>

class FunctionClass
{
 private:
  std::string mThreadName;
  int         mSleepTime;
  
 public:
  void operator()(std::promise promise)
  {
    std::this_thread::sleep_for(
                        std::chrono::milliseconds(mSleepTime));
    for (int i = 0; i < 3; i++)
    {
      std::cout << mThreadName;
    }
    std::cout << " ";
    promise.set_value(mSleepTime + 1000);
  }
  FunctionClass(std::string threadName, int sleepTime)
  : mThreadName(threadName), mSleepTime(sleepTime)
  {}
};

int main()
{
  FunctionClass f1("F1", 100);

  std::promise<int> promise1;
  std::future<int>  future1 = promise1.get_future();
  std::thread       t1(f1, std::move(promise1));

  future1.wait();
  std::cout << future1.get() << std::endl;

  t1.join();

  return 0;
}
// Output: F1F1F1 1100
Reference: http://en.cppreference.com/w/cpp/thread/promise

C++11: Future

C++11 added template class std::future that enables a thread to access the result of an asynchronous operation. Here is an example:

#include <chrono>
#include <future>
#include <iostream>
#include <string>
#include <thread>

class FunctionClass
{
 private:
  std::string mThreadName;
  int         mSleepTime;
  
 public:
  int operator()()
  {
    std::this_thread::sleep_for(
                        std::chrono::milliseconds(mSleepTime));
    for (int i = 0; i < 3; i++)
    {
      std::cout << mThreadName;
    }
    return mSleepTime + 1000;
  }
  FunctionClass(std::string threadName, int sleepTime)
  : mThreadName(threadName), mSleepTime(sleepTime)
  {}
};

int main()
{
  FunctionClass f1("F1", 300);
  FunctionClass f2("F2", 200);
  FunctionClass f3("F3", 100);

  std::packaged_task<int()> task3(f3)           ;
  std::future<int>          future3             = task3.get_future();
  std::thread               t1(f1)              ;
  std::thread               t2(f2)              ;
  std::thread               t3(std::move(task3));

  future3.wait();
  std::cout << future3.get();

  t1.join();
  t2.join();
  t3.join();

  std::cout << std::endl;
  return 0;
}
// Output: F3F3F31100F2F2F2F1F1F1
Reference: http://en.cppreference.com/w/cpp/thread/future

C++11: Atomics: Memory synchronization ordering

C++11 added Memory synchronization ordering:
memory_order
kill_dependency
atomic_thread_fence
atomic_signal_fence


C++11: Atomics: Flag Operations

C++11 added flag operations:
atomic_flag_test_and_set
atomic_flag_test_and_set_explicit
atomic_flag_clear
atomic_flag_clear_explicit

Here is an example:

#include <atomic>
#include <iostream>
using namespace std;

int main()
{
  atomic_flag memoryOrder = ATOMIC_FLAG_INIT;

  bool isMemoryOrderRelaxed=memoryOrder.test_and_set(memory_order_relaxed);
  bool isMemoryOrderConsume=memoryOrder.test_and_set(memory_order_consume);
  bool isMemoryOrderAcquire=memoryOrder.test_and_set(memory_order_acquire);
  bool isMemoryOrderRelease=memoryOrder.test_and_set(memory_order_release);
  bool isMemoryOrderAcqRel =memoryOrder.test_and_set(memory_order_acq_rel);
  bool isMemoryOrderSeqCst =memoryOrder.test_and_set(memory_order_seq_cst);

  cout << isMemoryOrderRelaxed << " ";
  cout << isMemoryOrderConsume << " ";
  cout << isMemoryOrderAcquire << " ";
  cout << isMemoryOrderRelease << " ";
  cout << isMemoryOrderAcqRel << " ";
  cout << isMemoryOrderSeqCst << " ";

  cout << endl;
  return 0;
}
// Output: 0 1 1 1 1 1
Reference: http://en.cppreference.com/w/cpp/atomic
                    http://en.cppreference.com/w/cpp/atomic/memory_order

C++11: Atomics: Operations

C++11 added atomic operations:
atomic_is_lock_free
atomic_store
atomic_store_explicit
atomic_load atomic_load_explicit
atomic_exchange
atomic_exchange_explicit
atomic_compare_exchange_weak
atomic_compare_exchange_weak_explicit
atomic_compare_exchange_strong
atomic_compare_exchange_strong_explicit
atomic_fetch_add
atomic_fetch_add_explicit
atomic_fetch_sub
atomic_fetch_sub_explicit
atomic_fetch_and
atomic_fetch_and_explicit
atomic_fetch_or
atomic_fetch_or_explicit
atomic_fetch_xor
atomic_fetch_xor_explicit

Here is an example:

#include <atomic>
#include <iostream>

int main()
{
  std::atomic<int> i = ATOMIC_VAR_INIT(0);

  std::atomic_fetch_add(&i, 1);
  std::cout << i << " ";

  std::atomic_fetch_sub(&i, 4);
  std::cout << i << " ";

  std::cout << std::endl;
  return 0;
}
// Output: 1 -3
Reference: http://en.cppreference.com/w/cpp/atomic

Monday, September 11, 2017

C++11: Condition Variables

C++11 added Condition Variables. Here is an example:

#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>

std::condition_variable gConditionVariable;
bool                    gEventIsTriggered = false;
std::mutex              gMutex;

struct FunctionClass
{
  void operator()()
  {
    std::cout << "ThreadWaiting:";
    std::unique_lock<std::mutex> lock(gMutex);
    gConditionVariable.wait(lock, []{return gEventIsTriggered;});
    std::cout << "ThreadExiting:";
  }
};

int main()
{
  std::thread t1{FunctionClass()};
  std::thread t2{FunctionClass()};

  std::cout << "MainRunning:";
  gEventIsTriggered = true;
  gConditionVariable.notify_one();
  gEventIsTriggered = true;
  gConditionVariable.notify_one();

  t1.join();
  t2.join();
  std::cout << std::endl;
  return 0;
}
// Output: ThreadWaiting:ThreadWaiting:MainRunning:ThreadExiting:ThreadExiting:
Reference: https://isocpp.org/wiki/faq/cpp11-library-concurrency#std-condition

C++11: Locks

C++11 added Locks. Here is an example:

#include <iostream>
#include <mutex>
#include <thread>

int gSharedData[2] = {1, 1};
std::mutex gMutex;

void updateData()
{
  std::unique_lock<std::mutex> lock(gMutex);
  gSharedData[0] = gSharedData[0] + 1;
  gSharedData[1] = gSharedData[1] + 1;
  std::cout << gSharedData[0] << " " << gSharedData[1] << " ";
}

struct FunctionClass
{
  void operator()()
  {
    int temp = 0;
    for (int i = 0; i < 3; i++)
    {
      updateData();
    }
  }
};

int main()
{
  std::thread t1{FunctionClass()};
  std::thread t2{FunctionClass()};
  std::thread t3{FunctionClass()};

  t1.join();
  t2.join();
  t3.join();
  std::cout << std::endl;
  return 0;
}
// Output: 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10
Reference: https://isocpp.org/wiki/faq/cpp11-library-concurrency#std-lock

C++11: Mutexes

C++11 added Mutexes. Here is an example:

#include <iostream>
#include <mutex>
#include <thread>

int gSharedData[2] = {1, 1};
std::mutex gMutex;

struct FunctionClass
{
  void operator()()
  {
    int temp = 0;
    for (int i = 0; i < 3; i++)
    {
      gMutex.lock();
      gSharedData[0] = gSharedData[0] + 1;
      gSharedData[1] = gSharedData[1] + 1;
      std::cout << gSharedData[0] << " " << gSharedData[1] << " ";
      gMutex.unlock();
    }
  }
};

int main()
{
  std::thread t1{FunctionClass()};
  std::thread t2{FunctionClass()};
  std::thread t3{FunctionClass()};

  t1.join();
  t2.join();
  t3.join();
  std::cout << std::endl;
  return 0;
}
// Output: 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10
Reference: https://isocpp.org/wiki/faq/cpp11-library-concurrency#std-mutex

C++11: Threads

C++11 added threading. Here is an example:

#include <chrono>
#include <iostream>
#include <string>
#include <thread>

class FunctionClass
{
 private:
  std::string mThreadName;
  int         mSleepTime;
  
 public:
  void operator()()
  {
    std::this_thread::sleep_for(std::chrono::seconds(mSleepTime));
    for (int i = 0; i < 3; i++)
    {
      std::cout << mThreadName;
    }
  }
  FunctionClass(std::string threadName, int sleepTime)
  : mThreadName(threadName), mSleepTime(sleepTime)
  {}
};

int main()
{
  FunctionClass f1("F1", 3);
  FunctionClass f2("F2", 2);
  FunctionClass f3("F3", 1);

  std::thread t1(f1);
  std::thread t2(f2);
  std::thread t3(f3);

  t1.join();
  t2.join();
  t3.join();
  std::cout << std::endl;
  return 0;
}
// Output: F3F3F3F2F2F2F1F1F1
Reference: https://isocpp.org/wiki/faq/cpp11-library-concurrency#std-threads

C++11: Algorithms: is_heap

C++11 added an is_heap algorithm. Here is an example:

#include <algorithm>
#include <iostream>

int main()
{
  int myArray[7]  = { 100,
                   50,     40,
                 20, 30,  10, 5};

  int * inIterBegin   = &myArray[0];
  int * inIterEnd     = &myArray[8];

  bool arrayIsAHeap = std::is_heap(inIterBegin , inIterEnd);
  
  std::cout << arrayIsAHeap << " ";

  myArray[1] = 200;
  arrayIsAHeap = std::is_heap(inIterBegin , inIterEnd);

  std::cout << arrayIsAHeap << std::endl;
  return 0;
}
// Output: 1 0
Reference: https://isocpp.org/wiki/faq/cpp11-library-stl#cpp11-algorithms

C++11: Algorithms: is_sorted

C++11 added an is_sorted algorithm. Here is an example:

#include <algorithm>
#include <iostream>

int main()
{
  int myArray[10]  = {1, 2, 3, 8, 9, 10, 10, 10, 10, 10};

  int * inIterBegin   = &myArray[0];
  int * inIterEnd     = &myArray[5];

  bool arrayIsSorted = std::is_sorted(inIterBegin , inIterEnd);
  
  std::cout << arrayIsSorted << " ";

  myArray[4] = 0;
  arrayIsSorted = std::is_sorted(inIterBegin , inIterEnd);

  std::cout << arrayIsSorted << std::endl;
  return 0;
}
// Output: 1 0
Reference: https://isocpp.org/wiki/faq/cpp11-library-stl#cpp11-algorithms

C++11: Algorithms: move_backward

C++11 added a move_backward algorithm. Here is an example:

#include <algorithm>
#include <iostream>

int main()
{
  int myArray[10]  = {1, 2, 3, 8, 9, 0, 0, 0, 0, 0};

  int * inIterBegin = &myArray[0];
  int * inIterEnd   = &myArray[2];
  int * outIterEnd  = &myArray[8];

  int * iter = std::move_backward(inIterBegin, inIterEnd, outIterEnd);
  
  for (auto element : myArray)
    std::cout << element << " ";

  std::cout << std::endl;
  return 0;
}
// Output: 1 2 3 8 9 0 1 2 0 0
// Microsoft compile warning: warning C4996:
//   'std::move_backward::_Unchecked_iterators::_Deprecate': ...
Reference: https://isocpp.org/wiki/faq/cpp11-library-stl#cpp11-algorithms

C++11: Algorithms: move

C++11 added a move algorithm. Here is an example:

#include <algorithm>
#include <iostream>

int main()
{
  int myArray[10]  = {1, 2, 3, 8, 9, 0, 0, 0, 0, 0};

  int * inIterBegin   = &myArray[0];
  int * inIterEnd     = &myArray[5];
  int * outIterBegin  = &myArray[5];

  int * iter = std::move(inIterBegin, inIterEnd, outIterBegin);
  
  for (auto element : myArray)
    std::cout << element << " ";

  std::cout << std::endl;
  return 0;
}
// Output: 1 2 3 8 9 1 2 3 8 9
// Microsoft compile warning: warning C4996:
//   'std::move::_Unchecked_iterators::_Deprecate': ...
Reference: https://isocpp.org/wiki/faq/cpp11-library-stl#cpp11-algorithms

C++11: Algorithms: copy_n

C++11 added a copy_n algorithm. Here is an example:

#include <algorithm>
#include <iostream>

int main()
{
  int myArray[10]  = {1, 2, 3, 8, 9, 0, 0, 0, 0, 0};

  int * inIterBegin   = &myArray[0];
  int * inIterEnd     = &myArray[5];
  int * outIterBegin  = &myArray[5];

  int * iter = std::copy_n(inIterBegin, 5, outIterBegin);
  
  for (auto element : myArray)
    std::cout << element << " ";

  std::cout << std::endl;
  return 0;
}
// Output: 1 2 3 8 9 1 2 3 8 9
// Microsoft compile warning: warning C4996:
//   'std::copy_n::_Unchecked_iterators::_Deprecate': ...
Reference: https://isocpp.org/wiki/faq/cpp11-library-stl#cpp11-algorithms

C++11: Algorithms: copy_if

C++11 added a copy_if algorithm. Here is an example:

#include <algorithm>
#include <iostream>

int main()
{
  int myArray[10]  = {1, 2, 3, 8, 9, 0, 0, 0, 0, 0};

  int * inIterBegin   = &myArray[0];
  int * inIterEnd     = &myArray[5];
  int * outIterBegin  = &myArray[5];

  int * iter = std::copy_if(inIterBegin , inIterEnd,
                            outIterBegin, 
                            [](int element){return element < 4;});
  
  for (auto element : myArray)
    std::cout << element << " ";

  std::cout << std::endl;
  return 0;
}
// Output: 1 2 3 8 9 1 2 3 0 0
// Microsoft compile warning: warning C4996:
//   'std::copy_if::_Unchecked_iterators::_Deprecate': ...
Reference: https://isocpp.org/wiki/faq/cpp11-library-stl#cpp11-algorithms

Friday, September 1, 2017

C++11: Containers: forward_list

A singly linked list was added. Here is an example:

#include <forward_list>
#include <iostream>

int main()
{
  std::forward_list<int> myList{3};

  myList.push_front(0);
  myList.push_front(1);
  myList.push_front(2);

  std::forward_list<int>::iterator iter = myList.begin();

  for (int element : myList) std::cout << " " << element;

  std::cout << ": ";

  std::cout << *iter << " "; iter = ++iter;
  std::cout << *iter << " "; iter = ++iter;
  std::cout << *iter << " "; iter = ++iter;
  std::cout << *iter << " "; iter = ++iter;

  std::cout << ": ";

  std::cout << myList.front() << " "; myList.pop_front();
  std::cout << myList.front() << " "; myList.pop_front();
  std::cout << myList.front() << " "; myList.pop_front();
  std::cout << myList.front() << " "; myList.pop_front();
  std::cout << std::endl;
  return 0;
}
// Output:  2 1 0 3: 2 1 0 3 : 2 1 0 3
Reference: https://isocpp.org/wiki/faq/cpp11-library-stl#forward-list

C++11: Containers: unordered_map, unordered_set, unordered_multimap, unordered_multiset

Hash containers were added. Here is an example.

#include <iostream>
#include <unordered_map>

int main()
{
  std::unordered_map<std::string, int> numbers{
                                         {"zero" , 0},
                                         {"one"  , 1},
                                         {"two"  , 2},
                                         {"three", 3}};
  std::cout << numbers["one"  ] << " " <<
               numbers["two"  ] << " " <<
               numbers["three"] << std::endl;

  return 0;
}
// Output: 1 2 3
Reference: https://isocpp.org/wiki/faq/cpp11-library-stl#std-unordered

C++11: Containers: array

An array container was added that does not have the overhead of a vector container. Here is an example:

#include <array>
#include <iostream>

int main()
{
  std::array<int, 7> a = {0, 1};
  
  a[6] = 6;

  std::cout << sizeof(a) << " " << a[0] << " "
                                << a[1] << " "
                                << a[6] << std::endl;
  return 0;
}
// Output: 28 0 1 6
Reference: https://isocpp.org/wiki/faq/cpp11-library-stl#cpp11-containers

C++11: Algorithms: iota

The function iota stores an increasing value in each element in a container. Here is an example:

#include <numeric>
#include <iostream>

int main()
{
  int myArray[5];

  int * beginIter = &myArray[0];
  int * endIter   = &myArray[5];

  std::iota(beginIter, endIter, 7);

  std::cout << myArray[0] << " " << 
               myArray[1] << " " <<
               myArray[2] << " " << std::endl;
  return 0;
}
// Output: 7 8 9
Reference: https://isocpp.org/wiki/faq/cpp11-library-stl#cpp11-algorithms

C++11: Algorithms: find_if_not

The find_if_not algorithm was added. Here is an example:

#include <algorithm>
#include <iostream>
 
int main()
{//                 0  1  2  3  4
  int myArray[]  = {1, 1, 1, 5, 1};
 
  int * beginIter = &myArray[0];
  int * endIter   = &myArray[5];
 
  int * iter = std::find_if_not(beginIter, endIter,
                                [](int element){return element == 1;});
 
  if (iter != endIter)
  {
    std::cout << *iter << " ";
  }
  else
  {
    std::cout << "Did not find anything ";
  }
 
  myArray[3] = 1;
  iter = std::find_if_not(beginIter, endIter,
                          [](int element){return element == 1;});
 
  if (iter != endIter)
  {
    std::cout << *iter << " ";
  }
  else
  {
    std::cout << "Did not find anything ";
  }
 
  std::cout << std::endl;
  return 0;
}
// Output: 5 Did not find anything
Reference: https://isocpp.org/wiki/faq/cpp11-library-stl#cpp11-algorithms

C++11: Algorithms: all_of, any_of, none_of

Given first and last iterators and a predicate, you can test to see if all, any or none of the elements in a container satisfies the predicates. Here is an example:

#include <algorithm>
#include <iostream>
int main()
{//                 0  1  2  3  4
  int allOnes[]  = {1, 1, 1, 1, 1};
  int someOnes[] = {1, 1, 1, 1, 0};

  int * beginIter = &allOnes[0];
  int * endIter   = &allOnes[5];

  bool allAreOnes = std::all_of  (beginIter, endIter,
                                  [](int element) {return element == 1;});
  std::cout << allAreOnes << " ";

  bool someAreOnes = std::any_of (beginIter, endIter,
                                  [](int element) {return element == 1;});
  std::cout << someAreOnes << " ";

  bool noneAreOnes = std::none_of(beginIter, endIter,
                                  [](int element) {return element == 1;});
  std::cout << noneAreOnes << " : ";

  beginIter = &someOnes[0];
  endIter  = &someOnes[5];

  allAreOnes = std::all_of  (beginIter, endIter,
                             [](int element) {return element == 1;});
  std::cout << allAreOnes << " ";

  someAreOnes = std::any_of (beginIter, endIter,
                             [](int element) {return element == 1;});
  std::cout << someAreOnes << " ";

  noneAreOnes = std::none_of(beginIter, endIter,
                             [](int element) {return element == 1;});
  std::cout << noneAreOnes << " ";

  return 0;
}
// Output: 1 1 0 : 0 1 0
Reference: https://isocpp.org/wiki/faq/cpp11-library-stl#cpp11-algorithms

C++11: Scoped Allocators

C++11 added to ability to write allocators that can maintain state. Here is an example:

#include <iostream>
#include <vector>

class Arena
{
  void * mPointerToMemory;
  int    mMaxNumberOfBytes;
  int    mNextAvailableByte;

 public:
  Arena(void * pointerToMemory, int maxNumberOfBytes)
  : mPointerToMemory(pointerToMemory),
    mMaxNumberOfBytes(maxNumberOfBytes),
    mNextAvailableByte(0)
  {
    ;
  }

  void * getPointerToBlockOfBytes(int numberOfBytes)
  {
    void * pointerToBlockOfBytes  = nullptr;
    int    remainingNumberOfBytes = mMaxNumberOfBytes - mNextAvailableByte;

    if (numberOfBytes <= remainingNumberOfBytes)
    {
      pointerToBlockOfBytes  = (void*)((unsigned char*)mPointerToMemory +
                                                       mNextAvailableByte);
      mNextAvailableByte    += numberOfBytes;       
    }
    return pointerToBlockOfBytes;
  }
};

template <class T>
struct MyAllocator
{
  typedef T value_type;

  Arena * mArena;

  MyAllocator(Arena * arena) : mArena(arena)
  {
    ;
  }

  template <class U>
  constexpr MyAllocator(const MyAllocator<U> & rhs) noexcept
  : mArena(rhs.mArena)
  {
    ;
  }

  T * allocate(std::size_t n)
  {
    void * pointerToBlockOfBytes = mArena->getPointerToBlockOfBytes(n);
    if (!pointerToBlockOfBytes)
    {
      throw std::bad_alloc();
    }
    return (T *) pointerToBlockOfBytes;
  }

  void deallocate(T* p, std::size_t) noexcept
  {
    ;
  }
};

template <class T, class U>
bool operator==(const MyAllocator<T>&, const MyAllocator<U>&)
{
  return true;
}

template <class T, class U>
bool operator!=(const MyAllocator<T>&, const MyAllocator<U>&)
{
  return false;
}

int main()
{
  Arena myArena(new int[8], 8);

  std::vector<int, MyAllocator<int>> v1(MyAllocator<int>{&myArena});

  std::cout << sizeof(v1) << " ";
  try{v1.push_back(0);}catch(...){std::cout << "Exception0" <<  " ";}
  std::cout << v1[0] << " ";
  try{v1.push_back(1);}catch(...){std::cout << "Exception1" <<  " ";}
  std::cout << v1[1] << " ";
  try{v1.push_back(2);}catch(...){std::cout << "Exception2" <<  " ";}
  std::cout << v1[2] << " ";
  try{v1.push_back(3);}catch(...){std::cout << "Exception3" <<  " ";}
  std::cout << v1[3] << " ";
  try{v1.push_back(4);}catch(...){std::cout << "Exception4" <<  " ";}
  std::cout << v1[4] << " ";

  std::cout << std::endl;
  return 0;
}
// Output: 20 0 1 2 Exception3
Reference: https://isocpp.org/wiki/faq/cpp11-library#scoped-allocator

C++11: Random Numbers: Distributions

C++11 provides the following distributions:
Uniform distributions:
  uniform_int_distribution
  uniform_real_distribution

Bernoulli distributions:
  bernoulli_distribution
  geometric_distribution
  binomial_distribution
  negative_binomial_distribution

Poisson distributions:
  poisson_distribution
  gamma_distribution
  exponential_distribution
  weibull_distribution
  extreme_value_distribution

Normal distributions:
  normal_distribution
  fisher_f_distribution
  cauchy_distribution
  lognormal_distribution
  chi_squared_distribution
  student_t_distribution

Sampling distributions:
  discrete_distribution
  piecewise_linear_distribution
  piecewise_constant_distribution

                     http://www.cplusplus.com/reference/random/


C++11: Random Numbers: Normal Distribution

You can easily create normally distributed numbers. Here is an example:

#include <iostream>
#include <random>
#include <vector>

std::normal_distribution<double>   norm_double_dist_0_9{4.5 /*mean*/,
                                                        2.0 /* sd */};
std::default_random_engine         random_engine{};
const int NbrOfBins    =  10;
const int NbrOfSamples = 100;

int main()
{
  std::vector<int> histogram(NbrOfBins);
  int              sampleValue;

  for (int sample = 0; sample < NbrOfSamples; ++sample)
  {
    sampleValue             = (int)norm_double_dist_0_9(random_engine);
    if (sampleValue < 0) sampleValue = 0;
    if (sampleValue > 9) sampleValue = 9;
    ++histogram[sampleValue];
  }

  for (int bin = 0; bin < NbrOfBins; ++bin)
  {
    std::cout << histogram[bin] << std::endl;
  }
  return 0;
}
/* Output:
     8
     6
     8
     15
     19
     18
     14
     8
     3
     1
*/
Reference: https://isocpp.org/wiki/faq/cpp11-library#std-random

C++11: Random Numbers

C++11 added more flexibility in generating random numbers. The system is divided into two parts: 1) A random number generator; and 2) a distribution. Each one can be set separately. Here is an example:

#include <iostream>
#include <random>
#include <vector>

std::uniform_int_distribution<int> uni_int_dist_0_9{0, 9};
std::default_random_engine         random_engine{};
const int NbrOfBins    =  10;
const int NbrOfSamples = 100;

int main()
{
  std::vector<int> histogram(NbrOfBins);
  int              sampleValue;

  for (int sample = 0; sample < NbrOfSamples; ++sample)
  {
    sampleValue             = uni_int_dist_0_9(random_engine);
    ++histogram[sampleValue];
  }

  for (int bin = 0; bin < NbrOfBins; ++bin)
  {
    std::cout << histogram[bin] << std::endl;
  }
  return 0;
}
/* Output:
    10
    6
    11
    10
    9
    9
    16
    6
    8
    15
*/
Reference: https://isocpp.org/wiki/faq/cpp11-library#std-random