Monday, October 23, 2017

C++17: Removal of std::random_shuffle

C++17 removed the random_shuffle() template function.

References:

C++17: Removal of std::auto_ptr

C++17 removed the auto_ptr template class.


C++17: "contiguous iterators"

C++17 added a new type of iterator called a contiguous iterator. It is a refinement of the random access iterator. The added constraints are that the elements are contiguous in memory. An example of this is vector, which can be used to interface with C.

References:

C++17: Uniform container access

C++17 added the non-member functions empty(), size(), and data(). These functions provide uniform access to C++ Library Containers.

References:

C++17: insert_or_assign

C++17 added the insert_or_assign() function to the map and unordered_map containers. The function inserts an element or assigns an element if the key already exists. Here is an example:

#include <iostream>
#include <map>
#include <string>

int main()
{
  std::map<std::string, std::string> myMap;
  myMap.insert_or_assign("a", "apple"     );
  myMap.insert_or_assign("b", "bannana"   );
  myMap.insert_or_assign("c", "cherry"    );
  myMap.insert_or_assign("c", "clementine");

  for (const auto &pair : myMap)
  {
    std::cout << pair.first << " : " << pair.second << "; ";
  }
  std::cout << std::endl;
  return 0;
}
// Output: a : apple; b : bannana; c : clementine;
References:
https://en.wikipedia.org/wiki/C%2B%2B17
http://en.cppreference.com/w/cpp/container/map/insert_or_assign

C++17: try_emplace

C++17 added the try_emplace() function to std:: map. The try_emplace() function stores a value if the key is not already there. Here is an example:

#include <iostream>
#include <map>
#include <string>

int main()
{
  std::map<std::string, std::string> myMap;
  myMap.try_emplace("a", "apple"     );
  myMap.try_emplace("b", "bannana"   );
  myMap.try_emplace("c", "cherry"    );
  myMap.try_emplace("c", "clementine");

  for (const auto &pair : myMap)
  {
    std::cout << pair.first << " : " << pair.second << "; ";
  }
  std::cout << std::endl;
  return 0;
}
// Output: a : apple; b : bannana; c : cherry;
Reference: https://en.wikipedia.org/wiki/C%2B%2B17

C++17: std::uncaught_exceptions

C++17 deprecated std::uncaught_exception and added std::uncaught_exceptions (The ‘s’ was added).

References:

C++17: std::any

C++17 added an any class that can hold any object. Here is an example.

#include <any>
#include <iostream>
 
int main()
{
  int      myInt  ;
  std::any myAny  ;
 
  std::cout << myAny.has_value() << " ";
  try
  {
    myInt = std::any_cast<int>(myAny);
  }
  catch(std::bad_any_cast e)
  {
    std::cout << "bad ";
  }
  std::cout << ": ";
  myAny = std::any(3);
  std::cout << myAny.has_value() << " ";
  try
  {
    myInt = std::any_cast<int>(myAny);
  }
  catch(std::bad_any_cast e)
  {
    std::cout << "bad ";
  }
  std::cout << myInt << " ";
  std::cout << std::endl;
  return 0;
}
// Output: 0 bad : 1 3
References:
https://en.wikipedia.org/wiki/C%2B%2B17
http://en.cppreference.com/w/cpp/utility/any

C++17: std::optional

C++17 added a template class that creates objects with optional values. Here is an example:

#include <iostream>
#include <optional>

int main()
{  
  std::optional<int> optionalInt;
  int                Int        ;

  Int = optionalInt.value_or(-1);
  std::cout << Int                     << " ";
  std::cout << optionalInt.has_value() << " ";
  try
  {
    Int = optionalInt.value();
  }
  catch(std::bad_optional_access e)
  {
    std::cout << "bad ";
  }
  std::cout << ": ";
  optionalInt = std::optional<int>(3);
  Int         = optionalInt.value_or(-1);
  std::cout << Int                     << " ";
  std::cout << optionalInt.has_value() << " ";
  try
  {
    Int = optionalInt.value();
  }
  catch(std::bad_optional_access e)
  {
    std::cout << "bad ";
  }
  std::cout << std::endl;
  return 0;
}
// Output: -1 0 bad : 3 1
References:
https://en.wikipedia.org/wiki/C%2B%2B17
http://en.cppreference.com/w/cpp/utility/optional/value

C++17: std::string_view

C++17 added the class template string_view, which is a kind of lightweight constant string. Here is an example:

#include <iostream>
#include <string>
#include <string_view>

int main()
{
  std::string_view myStringView("A rat in the house.");
  std::string myString;

  myString = myStringView;
  
  std::cout << myString     << " ";
  std::cout << myStringView << " ";

  std::cout << std::endl;
  return 0;
}
// Output: A rat in the house. A rat in the house.
References:
https://en.wikipedia.org/wiki/C%2B%2B17
http://en.cppreference.com/w/cpp/string/basic_string_view

Tuesday, October 17, 2017

C++17: Value of __cplusplus

C++17 changed the value of __cplusplus to 201703L



C++17: __has_include

C++17 added a macro that takes a header file name as an argument, and returns 1 if it was included already, and 0 if it was not. Here is an example:

#include <iostream>

#if __has_include(<iostream>) == 0
  #define INCLUDED_IOSTREAM_AGAIN true
  #include <iostream>
#else
  #define INCLUDED_IOSTREAM_AGAIN false
#endif

int main()
{
  if (INCLUDED_IOSTREAM_AGAIN)
  {
    std::cout << "Included  again." << std::endl;
  }
  else
  {
    std::cout << "Did not included  again." << std::endl;
  }
  return 0;
}
// Output: Did not included  again.
Reference: https://en.wikipedia.org/wiki/C%2B%2B17

C++17: Inline variables

C++17 allows inline variables. Here is an example:

inline static int gMyInt;
inline static int gMyInt;

int main()
{
  return 0;
}
Note: the code neither compiles on “gcc version 6.3.0” nor “MSVS 15.3.5”
Reference: https://en.wikipedia.org/wiki/C%2B%2B17

C++17: Template deduction of constructors

C++17 allows template deduction of constructors. Here is an example:

#include <iostream>

struct MyStruct
{
  template<typename T>
  MyStruct(T t)
  {
    std::cout << "T : ";
  }
};

template<>
MyStruct::MyStruct(int i)
{
  std::cout << "int : ";
}

template<>
MyStruct::MyStruct(double d)
{
  std::cout << "double : ";
}

int main()
{
  MyStruct myStructInt(1);
  MyStruct myStructDouble(2.2);
  MyStruct myStructString("Hello");
  std::cout << std::endl;

  return 0;
}
// Output: int : double : T :
Reference: https://en.wikipedia.org/wiki/C%2B%2B17

C++17: Extensions on over-aligned memory allocation

C++17 allows memory alignment greater than std::max_align_t. Here is an example:

#include <iostream>

class A
{
};

class alignas(8) B
{
};

class alignas(256) C // Over-aligned
{
};

class alignas(1024) D // Over-aligned
{
};

int main()
{
  A a;
  B b;
  C c;
  C d;

  std::cout << sizeof(std::max_align_t) << " ";
  std::cout << &a << " ";
  std::cout << &b << " ";
  std::cout << &c << " ";
  std::cout << &d << " ";
  std::cout << std::endl;
  return 0;
}
// Output: 8 0050FCF7 0050FCE0 0050FB00 0050F900
References:
https://en.wikipedia.org/wiki/C%2B%2B17
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0035r4.html

C++17: Initializers in if and switch statements

C++17 allows an initializer in if and switch statements. Here is an example:

#include <iostream>

int main()
{
  if (int i = 4; int j = 0)
  {
    std::cout << "Branch1 ";
  }
  else
  {
    std::cout << "Branch2 ";
  }

  if (int i = 0; int j = 5)
  {
    std::cout << "Branch1 ";
  }
  else
  {
    std::cout << "Branch2 ";
  }

  std::cout << ": ";

  switch (int i = 4; int j = 0)
  {
   case 0:
    std::cout << "Branch1 ";
    break;
   case 4:
    std::cout << "Branch2 ";
    break;
  }

  switch (int i = 0; int j = 5)
  {
   case 0:
    std::cout << "Branch1 ";
    break;
   case 5:
    std::cout << "Branch2 ";
    break;
  }
  std::cout << std::endl;
  return 0;
}
// Output: Branch2 Branch1 : Branch1 Branch2
References:
https://en.wikipedia.org/wiki/C%2B%2B17
http://www.modernescpp.com/index.php/cpp17-core

C++17: Structured binding declarations

C++17 provides structured binding declarations, which let you declare multiple variables initialized from a tuple or a struct. Here is an example:

#include <iostream>

struct MyStruct
{
  int    mA;
  int    mB;
  double mC;
  MyStruct() : mA(1), mB(2), mC(3.3) {};
};

int main()
{
  MyStruct myStruct;

  auto [a, b, c] = myStruct;

  std::cout << a << " " << b << " " << c << std::endl;
  return 0;
}
// Output: 1 2 3.3
References:
https://en.wikipedia.org/wiki/C%2B%2B17
https://skebanga.github.io/structured-bindings/

C++17: A compile-time static if

C++17 added a compile-time static if. It’s purpose is to allow the compiler to eliminate branches of an if statement. Here is an example:

#include <iostream>

int main()
{
  if constexpr (0)
  {
    std::cout << "Section Compiled Out" << " ";
  }
  else
  {
    std::cout << "Section Compiled In" << " ";
  }

  std::cout << std::endl;
  return 0;
}
// Output: Section Compiled In
References:
https://en.wikipedia.org/wiki/C%2B%2B17
https://tech.io/playgrounds/2205/7-features-of-c17-that-will-simplify-your-code/constexpr-if

C++17: Fold expressions for variadic templates

C++17 added fold expressions for variadic templates. Here is an example:

#include <iostream>

template<typename... Args>
bool AllTrueRight(Args... args) { return (args && ...); }

template<typename... Args>
bool AllTrueLeft(Args... args) { return (... && args); }

template<typename... Args>
int SumUnaryRight(Args... args) { return (args + ...); }

template<typename... Args>
int SumUnaryLeft(Args... args) { return (... + args); }

template<typename... Args>
int SubBinaryRight(Args... args) { return (args - ... - 100); }

template<typename... Args>
int SubBinaryLeft(Args... args) { return (100 - ... - args); }

int main()
{
  bool bResult = false;
  int  iResult = -1;

  bResult = AllTrueRight(true, true, true, false);
  std::cout << bResult << " "  ;

  bResult = AllTrueRight(true, true, true, true);
  std::cout << bResult << " "  ;

  bResult = AllTrueLeft(true, true, true, false);
  std::cout << bResult << " "  ;

  bResult = AllTrueLeft(true, true, true, true);
  std::cout << bResult << " "  ;

  iResult = SumUnaryLeft(1, 2, 3, 4);
  std::cout << iResult << " "  ;

  iResult = SumUnaryRight(1, 2, 3, 4);
  std::cout << iResult << " "  ;

  iResult = SubBinaryRight(10, 9, 8); // (10-(9-(8-100))) = 10-(9+92) = 10 - 101 = -91
  std::cout << iResult << " "  ;

  iResult = SubBinaryLeft(10, 9, 8); // (((100-10)-9)-8) = (90-9)-8 = 81-8 = 73
  std::cout << iResult << " "  ;

  std::cout << std::endl;
  return 0;
}
// Output: 0 1 0 1 10 10 -91 73
Notes:
1) Needed to use: gcc version 6.3.0 (MinGW.org GCC-6.3.0-1)
2) Commandline: g++ -std=c++17 *.cpp
References:
https://en.wikipedia.org/wiki/C%2B%2B17
http://en.cppreference.com/w/cpp/language/fold

C++17: Constant evaluation for all non-type template arguments

C++17 provides constant evaluation for all non-type template arguments. Here is an example:

#include <iostream>

template<int * p>
struct ST1
{
  int *mP = p; // C++98: Error; C++14: Good
};

template<int * i> 
struct ST2
{
  int mI = *i; // C++98: Error; C++14: Good
};

template<int (*pf)()>
struct ST3
{
  int mI = pf(); // C++98: Error; C++14: Good
};

struct S
{
  static int m;
};

int S::m = 42;
int gI   = 55;

///////////////////////////////////////////////////////////////////////////////
int myFunc()
{
  return 211;
}

///////////////////////////////////////////////////////////////////////////////
int main()
{
  S           s   ;
  ST1<&s.m  > st11; // C++14: Error, c++17: Good
  ST1<&S::m > st12;
  ST2<&gI   > st21;
  ST3<myFunc> st31;

  std::cout <<  s.m     << " ";
  std::cout << *st11.mP << " ";
  std::cout << *st12.mP << " ";
  std::cout <<  st21.mI << " ";
  std::cout <<  st31.mI << " ";

  std::cout << std::endl;
  return 0;
}
// Output: 42 42 42 55 211
References:
https://en.wikipedia.org/wiki/C%2B%2B17
https://stackoverflow.com/questions/33301552/non-type-reference-parameter-argument
https://isocpp.org/files/papers/n4268.html

Tuesday, October 10, 2017

C++17: [[maybe_unused]] Attribute

C++17 the [[maybe_unused]] attribute to handle a case where a variable is only sometimes used during a compile. An example of this is a variable that is only used in an assert() statement. When compiled in debug mode, this variable would be used; but when compiled in release mode, this variable would not be used.  This attribute disables the unused variable warning for variables specified with this attribute.

References:

C++17: Hexadecimal Floating-Point Literals

C++17 added hexadecimail floating-point literals. They are of the form 0x<hex_wholenumber>.<hex_fraction>p<power_of_2>. Here is an example:

#include <iostream>

int main()
{
  std::cout << 0x0p0     << " "; // ( 0.0/16.0 + 0.0/16     )*(2.0 ** 0.0)
  std::cout << 0x0.p0    << " "; // ( 0.0/16.0 + 0.0/16     )*(2.0 ** 0.0)
  std::cout << 0x.1p0    << " "; // ( 0.0/16.0 + 1.0/16     )*(2.0 ** 0.0)
  std::cout << 0x0.1p0   << " "; // ( 0.0/16.0 + 1.0/16     )*(2.0 ** 0.0)
  std::cout << 0x1.1p0   << " "; // ( 1.0/16.0 + 1.0/16     )*(2.0 ** 0.0)
  std::cout << 0x1.2p0   << " "; // ( 1.0/16.0 + 2.0/16     )*(2.0 ** 0.0)
  std::cout << 0x2.2p0   << " "; // ( 2.0/16.0 + 2.0/16     )*(2.0 ** 0.0)
  std::cout << 0x2.2p1   << " "; // ( 2.0/16.0 + 2.0/16     )*(2.0 ** 1.0)
  std::cout << 0x2.2p2   << " "; // ( 2.0/16.0 + 2.0/16     )*(2.0 ** 2.0)
  std::cout << 0x10.01p0 << " "; // (16.0/16.0 + 1.0/(16*16))*(2.0 ** 0.0)
  std::cout << 0x0.001p0 << " "; // (16.0/16.0 + 1.0/(16**3))*(2.0 ** 0.0)

  std::cout << std::endl;
  return 0;
}
// Output: 0 0 0.0625 0.0625 1.0625 1.125 2.125 4.25 8.5 16.0039 0.000244141
References:

C++17: Utf-8 Character Literals

C++17 added Utf-8 literals. They are specified with a u8 prefix.  Here is an example: auto c = u8’a’;


C++17: [[nodiscard]] Attribute

C++17 added the [[nodiscard]] attribute to specify that any function call that returns a value, has that value stored in the calling code, or else a warning is given: Here is an example:

[[nodiscard]]
int func()
{
  return 0;
}

int main()
{
  func();
  return 0;
}
// Compiler Warning: warning C4834: discarding return value of function
                                                with 'nodiscard' attribute
References:
https://en.wikipedia.org/wiki/C%2B%2B17
https://infektor.net/posts/2017-01-19-using-cpp17-attributes-today.html

C++17: [[fallthrough]] Attribute

C++17 added the [[fallthrough]] attribute to help protect against forgetting a break statement in a case statement. If a break is missing and the [[fallthrough]] attribute is not given then a warning may be given by the compiler.  MSVS 2017 does not handle this attribute.

References:

C++17: Shortened Nested Namespace Definitions

C++17 allows nested namespace definitions to be shortened.

Instead of:

namespace N1 { namespace N2 {
}}

You can write:

namespace N1::N2 {
}
Reference: https://en.wikipedia.org/wiki/C%2B%2B17

C++17: New Rules for auto Deduction

Auto deduction for direct-list initialization must have only a single element. Here is an example:

int main()
{
  //auto v = {9, 10}; //Should be good, but error in MSVS 2017:
                      //  Copy-list-initialization. decltype(y) is
                      //  std::initializer_list.
  //auto w = {1, 2.0};//Error: Copy-list-initialization and types of 
                      //  elements of braced-init-list are not identical.
    auto x{3};        //Good: Direct list-initilization and single element.
                      //  decltype(x) is int.
  //auto y     = {3}; //Should be good, but error in MSVS 2017:
                      //  Copy-list-initialization. decltype(y) is
                      //  std::initializer_list.
  //auto z{3, 4};     //Error: Direct list-initialization and multiple
                      //  elements.
  return 0;
}
References:
https://en.wikipedia.org/wiki/C%2B%2B17
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3922.html

C++17: Template template parameter can be declared typename

Before C++17 , a template template parameter had to be declared class. Here is an example:

#include <complex>
#include <iostream>

//                +----- Template Parameter
//                |
//                V                          
template<typename T>
class A
{
 public:
  T mT = T();
}; 
//                                  +----- Template Template Parameter
//                                  |
//                                  V                          
template<  template<typename> class U  >
class B
{
 public:
  U<int> mU;
};
//                                  +----- Template Template Parameter
//                                  |
//                                  V                          
template<  template<typename> class U  >
class C
{
 public:
  U<std::complex<double>> mU;
};

int main()
{
  B<A> b;

  std::cout << b.mU.mT << " ";

  C<A> c;

  std::cout << c.mU.mT << std::endl;

  return 0;
}
// Output: 0 (0,0)
Reference: https://en.wikipedia.org/wiki/C%2B%2B17

C++17: Trigraphs Removed

C++17 removed trigraphs. Trigraphs are three-character sequences representing one character. They were a workaround for some keyboards not having cetain characters. Here is an example of trigraphs in C++98.

#include <iostream>

int main()
{
  std::cout << "??="  << " "; // #
  std::cout << "??//" << " "; // /
  std::cout << "??'"  << " "; // ^
  std::cout << "??)"  << " "; // ]
  std::cout << "??("  << " "; // [
  std::cout << "??!"  << " "; // |
  std::cout << "??<"  << " "; // {
  std::cout << "??>"  << " "; // }
  std::cout << "??-"  << " "; // ~

  std::cout << std::endl;
}
// Output: # / ^ ] [ | { } ~
References:
https://en.wikipedia.org/wiki/C%2B%2B17
https://stackoverflow.com/questions/1234582/purpose-of-trigraph-sequences-in-c

C++17: Static_assert Message Optional

C++17 makes the text message for static_assert optional.


Tuesday, October 3, 2017

C++14: The std::quoted

C++14 allows you to quote strings. Here is an example:

#include <iomanip>
#include <iostream>

int main()
{
  std::cout << std::quoted("To quote: \"Hello.\"  ");
  std::cout <<             "To quote: \"Hello.\"  ";
  std::cout << std::endl;
  return 0;
}
// Output: "To quote: \"Hello.\"  "To quote: "Hello."
Reference: https://en.wikipedia.org/wiki/C%2B%2B14#Smaller_library_features

C++14: std::cbegin/std::cend/std::crbegin/std::crend

C++14 added functions that return constant iterators.


C++14: std::integer_sequence

C++14 added integer_sequence template class

#include <iostream>
#include <vector>
#include <utility>

void myPrintFunction(int a, int b, int c, int d)
{
std::cout << a << " " << b << " " << c << " " << d << std::endl;
}

template<typename T, T... Sequence>
void myTemplateFunction(std::integer_sequence<T, Sequence...>)
{
  myPrintFunction(Sequence...);
}

int main()
{
  std::integer_sequence<int, 2, 4, 6, 8> mySequence;
 
  myTemplateFunction(mySequence);

  return 0;
}
// Output: 2 4 6 8
Reference: https://cpprefjp.github.io/reference/utility/integer_sequence.html

C++14: std::integral_constant gained an operator()

C++14 added the member function operator() to integral_constant. Integral_constant wraps a static constant. operator() returns the constants value. Here is an example:

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

integral_constant<long long, 42ll> Answer;

int main()
{
  cout << Answer()     << " ";
  cout << Answer.value << " ";
  cout <<        integral_constant<long long, 42ll>::value_type(Answer) << " ";
  cout <<        integral_constant<long long,  0ll>::value_type(Answer) << " ";
  cout << sizeof(integral_constant<long long, 42ll>::value_type)        << " ";
  cout << sizeof(integral_constant<long long, 42ll>::type      )        << " ";

  cout << endl;
  return 0;
}
// Output: 42 42 42 42 8 1
Reference: http://www.cplusplus.com/reference/type_traits/integral_constant/

C++14: std::make_unique

C++14 added the make_unique template function to construct an object and wrap a unique_ptr around it. Here is an example:

#include <memory>

int main()
{
  std::unique_ptr<int  > myInt      = std::make_unique<int  >(42);
  std::unique_ptr<int[]> myIntArray = std::make_unique<int[]>(42);
  
  return 0;
}
Reference: http://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique

C++14: Tuple addressing via type

C++14 added addressing a tuple component by type. Here is an example:

#include <iostream>
#include <string>
#include <tuple>

int main()
{
  std::tuple
                                        myTuple(1, 2, 3, 4.4f, 5.5, "six");

  std::cout << std::get<int        >(myTuple) << " ";
  std::cout << std::get<long       >(myTuple) << " ";
  std::cout << std::get<short      >(myTuple) << " ";
  std::cout << std::get<float      >(myTuple) << " ";
  std::cout << std::get<double     >(myTuple) << " ";
  std::cout << std::get<std::string>(myTuple) << " ";

  std::cout << std::endl;

  return 0;
}
// Output: 1 2 3 4.4 5.5 six
Reference: http://developeradventure.blogspot.com/2013/12/c14-tuple-addressing-via-type.html

C++14: Standard user-defined literals

C++14 defined several standard user-defined literals:
operator""if          imaginary float      std::literals::complex_literals
operator""I           imaginary double  std::literals::complex_literals
operator""il          imaginary long      std::literals::complex_literals
operator""h          hours                      std::literals::chrono_literals
operator""min      minutes                  std::chrono::duration
operator""s          seconds                   std::chrono::duration
operator""ms       milliseconds           std::chrono::duration
operator""us        microseconds         std::chrono::duration
operator""ns        nanoseconds          std::chrono::duration
operator""s          string                      std::literals::string_literals


Here is an example:

#include <chrono>
#include <complex>
#include <iostream>

int main()
{
  using namespace std::complex_literals;
  std::cout << 1.1if << " ";
  std::cout << 2.2i  << " ";
  std::cout << 3il   << " ";

  using namespace std::chrono_literals;
  std::cout << std::chrono::seconds    (4h  ).count() << " ";
  std::cout << std::chrono::seconds    (5min).count() << " ";
  std::cout << std::chrono::seconds    (6s  ).count() << " ";
  std::cout << std::chrono::nanoseconds(7ms ).count() << " ";
  std::cout << std::chrono::nanoseconds(8us ).count() << " ";
  std::cout << std::chrono::nanoseconds(9ns ).count() << " ";

  using namespace std::string_literals;
  std::cout << "Hello"s << " ";

  std::cout << std::endl;
  return 0;
}
// Output: (0,1.1) (0,2.2) (0,3) 14400 300 6 7000000 8000 9 Hello
Reference: http://en.cppreference.com/w/cpp/language/user_literal

C++14: Heterogeneous lookup in associative containers

C++14 added heterogeneous lookup in associative containers. It is enabled by specifying ‘less<>’ in the container template. Here is an example:

#include <iostream>
#include <functional>
#include <set>
using namespace std;

class MyClass0
{
  int mId;
 public:
  MyClass0(int id) : mId(id) {cout << "CTOR0 ";}
  bool operator< (const MyClass0 & rhs) const
  {
    return this->mId < rhs.mId;
  }
};

class MyClass1
{
  int mId;
 public:
  MyClass1(int id) : mId(id) {cout << "CTOR1 ";}
  bool operator< (const MyClass1 & rhs) const
  {
    return this->mId < rhs.mId;
  }
};

class MyClass2
{
  int mId;
 public:
  MyClass2(int id) : mId(id) {cout << "CTOR2 ";}
  bool operator< (const MyClass2 & rhs) const
  {
    return this->mId < rhs.mId;
  }
};

int main()
{
  set<MyClass0                 > mySet0;
  set<MyClass1, less<        > > mySet1; // Allows Heterogeneous Lookup.
  set<MyClass2, less<MyClass2> > mySet2;

  set<MyClass0                 >::iterator mySet0_iter;
  set<MyClass1, less<        > >::iterator mySet1_iter;
  set<MyClass2, less<MyClass2> >::iterator mySet2_iter;

  MyClass0 myObject0_1(1);
  mySet0.insert(myObject0_1);
  mySet0_iter=mySet0.find(myObject0_1);cout<<(mySet0_iter!=mySet0.end())<<" ";
  mySet0_iter=mySet0.find(MyClass0(1));cout<<(mySet0_iter!=mySet0.end())<<" ";
  mySet0_iter=mySet0.find(1          );cout<<(mySet0_iter!=mySet0.end())<<" ";
  cout << endl;

  MyClass1 myObject1_1(1);
  mySet1.insert(myObject1_1);
  mySet1_iter=mySet1.find(myObject1_1);cout<<(mySet1_iter!=mySet1.end())<<" ";
  mySet1_iter=mySet1.find(MyClass1(1));cout<<(mySet1_iter!=mySet1.end())<<" ";
  // The following does not compile in MSVS2014.
  //mySet1_iter=mySet1.find(1          );cout<<(mySet1_iter!=mySet1.end())<<" ";
  cout << endl;

  MyClass2 myObject2_1(1);
  mySet2.insert(myObject2_1);
  mySet2_iter=mySet2.find(myObject2_1);cout<<(mySet2_iter!=mySet2.end())<<" ";
  mySet2_iter=mySet2.find(MyClass2(1));cout<<(mySet2_iter!=mySet2.end())<<" ";
  mySet2_iter=mySet2.find(1          );cout<<(mySet2_iter!=mySet2.end())<<" ";

  cout << endl;
  return 0;
}
// Output(MSVS): CTOR0 1 CTOR0 1 CTOR0 1
//               CTOR1 1 CTOR1 1
//               CTOR2 1 CTOR2 1 CTOR2 1
//
// Output(g++):  CTOR0 1 CTOR0 1 CTOR0 1
//               CTOR1 1 CTOR1 1 CTOR1 1
//               CTOR2 1 CTOR2 1 CTOR2 1
Reference: https://en.wikipedia.org/wiki/C%2B%2B14#Heterogeneous_lookup_in_associative_containers

C++14: Shared Lock Type

C++14 added a Shared Lock Type. Here is an example:

#include <iostream>
#include <mutex>
#include <shared_mutex>

int main()
{
  std::shared_timed_mutex MySharedTimedMutex;

  std::shared_lock<std::shared_timed_mutex>
                                    MySharedLock(MySharedTimedMutex);
  if (MySharedLock.owns_lock())
  {
    std::cout << "R+ ";
  }
  else
  {
    std::cout << "R- ";
  }

  std::shared_lock<std::shared_timed_mutex>
                                   MySharedLock2(MySharedTimedMutex);

  if (MySharedLock2.owns_lock())
  {
    std::cout << "R+ ";
  }
  else
  {
    std::cout << "R- ";
  }

  MySharedLock.unlock();
  MySharedLock2.unlock();

  std::unique_lock<std::shared_timed_mutex>
                                    MyUniqueLock(MySharedTimedMutex);
  if (MyUniqueLock.owns_lock())
  {
    std::cout << "W+ ";
  }
  else
  {
    std::cout << "W- ";
  }
  return 0;
}
// Output: R+ R+ W+
Reference: http://en.cppreference.com/w/cpp/thread/shared_lock/shared_lock

C++14: Shared Timed Mutex

C++14 added a shared timed mutex. You can lock something as shared (like a reader lock) or exclusive (like a writer lock). Here is an example:

#include <iostream>
#include <shared_mutex>

int main()
{
  std::shared_timed_mutex MySharedTimedMutex;

  if (MySharedTimedMutex.try_lock_shared())
  {
    std::cout << "R+ ";
  }
  else
  {
    std::cout << "R- ";
  }
  if (MySharedTimedMutex.try_lock_shared())
  {
    std::cout << "R+ ";
  }
  else
  {
    std::cout << "R- ";
  }
  if (MySharedTimedMutex.try_lock())
  {
    std::cout << "W+ ";
  }
  else
  {
    std::cout << "W- ";
  }
  MySharedTimedMutex.unlock_shared();
  MySharedTimedMutex.unlock_shared();
  if (MySharedTimedMutex.try_lock())
  {
    std::cout << "W+ ";
  }
  else
  {
    std::cout << "W- ";
  }
  return 0;
}
// Output: R+ R+ W- W+
Reference: http://en.cppreference.com/w/cpp/thread/shared_timed_mutex

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

Tuesday, August 29, 2017

C++11: Time: Durations

Durations can only be set with whole numbers. For example, to specify a 1.5 second duration, you need to specify 1500 milliseconds.


C++11: Time: Durations

C++11 has new duration types that can be used with the new time functions.

#include <chrono>
#include <iostream>

int main()
{
  std::chrono::nanoseconds  ns(9'000'000);
  std::chrono::microseconds us(60'000);
  std::chrono::milliseconds ms(300);
  std::chrono::seconds       s(1);

  std::chrono::high_resolution_clock::duration hrc_duration = s + ms + us + ns;

  double hrc_seconds = double(hrc_duration.count())                    *
                       std::chrono::high_resolution_clock::period::num /
                       std::chrono::high_resolution_clock::period::den;  

  std::cout << hrc_seconds << std::endl;

  return 0;
}
// Output: 1.369
Reference: http://en.cppreference.com/w/cpp/chrono/duration

C++11: Time

Three time systems were added. Here is an example:

#include <chrono>
#include <ctime>
#include <iostream>

int main()
{
////
  std::chrono::system_clock::time_point syc_now      = 
                                         std::chrono::system_clock::now();
  std::chrono::system_clock::time_point syc_default  ;
  std::chrono::system_clock::duration   syc_duration = syc_now -
                                                              syc_default;

  double syc_seconds = double(syc_duration.count())           *
                       std::chrono::system_clock::period::num /
                       std::chrono::system_clock::period::den; 

  std::cout << syc_seconds << std::endl;
////
  std::chrono::steady_clock::time_point stc_now     =                                             std::chrono::steady_clock::now();
  std::chrono::steady_clock::time_point stc_default ;
  std::chrono::steady_clock::duration   stc_duration = stc_now -
                                                            stc_default;

  double std_seconds = double(stc_duration.count())           *
                       std::chrono::steady_clock::period::num /
                       std::chrono::steady_clock::period::den;  

  std::cout << std_seconds << std::endl;
////
  std::chrono::high_resolution_clock::time_point hrc_now      =                                   std::chrono::high_resolution_clock::now();
  std::chrono::high_resolution_clock::time_point hrc_default  ;
  std::chrono::high_resolution_clock::duration   hrc_duration = 
                                                   hrc_now - hrc_default;

  double hrc_seconds = double(hrc_duration.count())                    *
                       std::chrono::high_resolution_clock::period::num /
                       std::chrono::high_resolution_clock::period::den;  

  std::cout << hrc_seconds << std::endl;
////
  std::time_t tt_now = std::time(nullptr);

  std::cout << tt_now << std::endl;
  return 0;
}
/* Output:
     1.50396e+09
     33785.6
     33785.6
     1503960804
*/
Reference: http://www.cplusplus.com/reference/chrono/