#pragma once
#ifndef __MODERN_CPP_11_H
#define __MODERN_CPP_11_H
#include <thread>
#include <vector>
#include <unordered_map>
#include <initializer_list>
// global macros
#define IGNORE_EXCEPTION(METHOD) { try { METHOD(); } catch (...) {} }
typedef double double_t; // OLD: define double_t as an alias for type double
using double_t = double; // C++11: exactly SAME as above! use 1 or the other
using namespace std;
// https://www.learncpp.com/cpp-tutorial/b-1-introduction-to-c11/
namespace MODERNCPP
{
// C++11, tells the compiler not to instantiate the template in this translation unit.
extern template class std::vector<std::string>;
// for enum casting
enum class WeekDay { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday };
template <typename Enumeration>
auto as_integer(Enumeration const value)
-> typename std::underlying_type<Enumeration>::type
{
return static_cast<typename std::underlying_type<Enumeration>::type>(value);
}
// for static_assert
template <class T>
void swap(T& a, T& b)
{
static_assert(std::is_copy_constructible<T>::value,
"Swap requires copying");
static_assert(std::is_nothrow_copy_constructible<T>::value
&& std::is_nothrow_copy_assignable<T>::value,
"Swap requires nothrow copy/assign");
auto c = b;
b = a;
a = c;
}
template <class T>
struct data_structure
{
static_assert(std::is_default_constructible<T>::value,
"Data Structure requires default-constructible elements");
};
// Variadic template
template<typename T>
T adder(T v) { return v; }
template<typename T, typename... Args>
T adder(T first, Args... args) { return first + adder(args...); }
// A generic function which finds minimum of two values
// return type is type of variable which is minimum
template <class A, class B>
auto findMin(A a, B b) -> decltype(a < b ? a : b)
{
return (a < b) ? a : b;
}
// ignore exceptions
template< typename Callable, typename... Arguments > void
Ingnore_Exceptions(Callable && _method, Arguments && ... args) noexcept
{
try { _method(::std::forward< Arguments >(args)...); } catch (...) {} // Do nothing.
}
// explicit default and delete
struct no_copy
{
no_copy(const no_copy&) = delete;
no_copy() = default;
};
struct no_default
{
no_default() = delete;
};
class Base {
public:
virtual ~Base() noexcept {} // C++11, compile-time check make sure no throw
virtual bool BaseMethod() { return false; }
virtual void BaseMethod(int n) final {} // not overridable at sub-classes
virtual const char* getName() const { return "Base"; }
virtual int getValue() const { return m_value; }
virtual void setValue(int value) { m_value = value; }
public:
int m_value{ 0 };
};
class Cpp11 : public Base {
public:
explicit Cpp11() noexcept {} // cannot called implicitly
Cpp11(Cpp11&&); // MovableClass, typical declaration of a move constructor.
Cpp11& operator=(Cpp11&& c); // MovableClass operator =
//Cpp11&& operator=(Cpp11&&) = default; // Forcing a move constructor to be generated by the compiler.
//Cpp11&& operator=(Cpp11&&) = delete; // Avoiding implicit move constructor.
Cpp11(int id) : Cpp11(id, 1) {} // Use a delegating constructors to minimize redundant code
Cpp11(int id1, int id2 = 0) : count(0), member(id2) {}
Cpp11(const std::initializer_list<int> &); // using initializer list
Cpp11& operator=(const std::initializer_list<int> &); // inializer list assignment made possible
int& operator[](int); // overload [] for array access
constexpr int ConstExpr(int x, int y) { return (x * y); } // const expression
// overrides
bool BaseMethod() override { return true; }
const char* getName() const override { return "Cpp11"; }
long getLength() { return m_vMap.size(); }
void ForEachLoop();
long EnumClass(WeekDay);
// LAMBDAs
// https://en.cppreference.com/w/cpp/language/lambda
int x, y;
int operator()(int);
void Lambda();
void StaticAssert(); // Performs compile-time assertion checking
long PseudoNumberGenerator(int, int); // using default engine seed
long RandomNumberGenerator(int, int); // using mt19937 engine seed
void Tuple(); // multiple value returns, instead of struct
void UniquePtr(); // C++11, most used smart pointer
void NullPtr(std::nullptr_t ptr) {} // accepts nullptr, sucessor to NULL
void ReferenceWrapper();
void InitializerList();
void VariadicTemplate();
void UnorderedContainers();
void RegularExpression();
void VariableSizes();
auto TrailingReturnType() const -> int;
void DeclType();
// for threading
// https://thispointer.com/c-11-multithreading-part-1-three-different-ways-to-create-threads/
static void DoWork(void*);
void DoWorkInternal();
std::thread DoWorkAsync(int);
void ParallelThreads();
void ProducerConsumer();
void DetachedThread();
// Indicates that the function does not return.
[[noreturn]] void NoReturn() { throw "error"; } // OK
// friend
friend std::ostream& operator<<(std::ostream&, const Cpp11&);
private:
// tuple
std::tuple<int, double> ReturnTuple();
private:
// initialize
int member = 0;
int count{}; // uniform initialization, default initialization to 0
std::vector<int> m_vMap = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
// Create an unordered_map of three strings (that map to strings)
std::unordered_map<std::string, std::string> u = {
{"RED","#FF0000"},
{"GREEN","#00FF00"},
{"BLUE","#0000FF"}
};
// smart pointers
// https://www.codeproject.com/Articles/541067/Cplusplus-Smart-Pointers
//std::auto_ptr<Base> ap; // C++98, deprecated in C++17
std::shared_ptr<Base> sp = std::make_shared<Base>(); // C++11, released until all shared pointer out of scope
std::weak_ptr<Base> wp = sp; // C++11, shared pointer, resolve cyclic reference
std::unique_ptr<Base> up; // C++11, replacement for auto pointer, 1 reference
};
}
#endif