From 585965ec7ca1a8146a7ac688873f2b8a077a104b Mon Sep 17 00:00:00 2001 From: Alex Hirsch Date: Thu, 21 Jan 2021 15:08:19 +0100 Subject: [PATCH] Add little features topic --- topic/little_features/.gitignore | 1 + topic/little_features/CMakeLists.txt | 13 ++++ topic/little_features/conversion_operator.cpp | 19 ++++++ topic/little_features/execution_policy.cpp | 15 +++++ topic/little_features/placement_new.cpp | 23 ++++++++ topic/little_features/pointer_to_member.cpp | 59 +++++++++++++++++++ 6 files changed, 130 insertions(+) create mode 100644 topic/little_features/.gitignore create mode 100644 topic/little_features/CMakeLists.txt create mode 100644 topic/little_features/conversion_operator.cpp create mode 100644 topic/little_features/execution_policy.cpp create mode 100644 topic/little_features/placement_new.cpp create mode 100644 topic/little_features/pointer_to_member.cpp diff --git a/topic/little_features/.gitignore b/topic/little_features/.gitignore new file mode 100644 index 0000000..0ec9e7f --- /dev/null +++ b/topic/little_features/.gitignore @@ -0,0 +1 @@ +/build* diff --git a/topic/little_features/CMakeLists.txt b/topic/little_features/CMakeLists.txt new file mode 100644 index 0000000..137af03 --- /dev/null +++ b/topic/little_features/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 3.16) +project(little_features CXX) + +file(GLOB srcs *.cpp) +foreach(src IN LISTS srcs) + get_filename_component(exe ${src} NAME_WE) + add_executable(${exe} ${src}) + target_compile_features(${exe} PRIVATE cxx_std_17) + set_target_properties(${exe} PROPERTIES CXX_EXTENSIONS OFF) + target_compile_options(${exe} PRIVATE + $<$:-Wall -Wextra -pedantic>) + target_link_libraries(${exe} -ltbb) +endforeach() diff --git a/topic/little_features/conversion_operator.cpp b/topic/little_features/conversion_operator.cpp new file mode 100644 index 0000000..920d1d9 --- /dev/null +++ b/topic/little_features/conversion_operator.cpp @@ -0,0 +1,19 @@ +#include + +struct Vec3 { + float x, y, z; +}; + +struct Vec2 { + float x, y; + operator Vec3() const { return Vec3{x, y, 0}; } +}; + +int main() +{ + Vec2 v2{1, 2}; + + Vec3 v3 = v2; + + assert(v3.x == 1 && v3.y == 2 && v3.z == 0); +} diff --git a/topic/little_features/execution_policy.cpp b/topic/little_features/execution_policy.cpp new file mode 100644 index 0000000..7ea3652 --- /dev/null +++ b/topic/little_features/execution_policy.cpp @@ -0,0 +1,15 @@ +#include +#include +#include +#include + +int main() +{ + std::vector numbers; + for (auto i = 0; i < 1000; i++) { + numbers.push_back(i); + } + + // Output should be malformed since there is no synchronization in place. + std::for_each(std::execution::par, numbers.begin(), numbers.end(), [](int i) { std::cout << i << "\n"; }); +} diff --git a/topic/little_features/placement_new.cpp b/topic/little_features/placement_new.cpp new file mode 100644 index 0000000..92cb562 --- /dev/null +++ b/topic/little_features/placement_new.cpp @@ -0,0 +1,23 @@ +#include +#include + +struct Point { + Point(float x, float y) : x(x), y(y) { std::cout << "Constructed at address: " << this << "\n"; } + ~Point() { std::cout << "Deconstructed at address: " << this << "\n"; } + float x, y; +}; + +int main() +{ + auto memory = malloc(sizeof(Point)); + + // Construct a point at a specific location. + Point *p = new (memory) Point(1.0f, 2.0f); + + std::cout << "x: " << p->x << "\n"; + + // Need to manually invoke the destructor. + p->~Point(); + + free(memory); +} diff --git a/topic/little_features/pointer_to_member.cpp b/topic/little_features/pointer_to_member.cpp new file mode 100644 index 0000000..e0375ea --- /dev/null +++ b/topic/little_features/pointer_to_member.cpp @@ -0,0 +1,59 @@ +#include + +struct Point { + float x, y; +}; + +struct Rect { + Point tl, br; + float area() const { return (br.x - tl.x) * (br.y - tl.y); } +}; + +class IShape { + public: + virtual float area() const { assert(false); }; + virtual ~IShape() {} +}; + +class Square : public IShape { + public: + Square(float extend) : m_extend(extend) {} + float area() const override { return m_extend * m_extend; } + + private: + float m_extend; +}; + +int main() +{ + Rect r1{{1, 1}, {4, 4}}; + assert(r1.area() == 9.0f); + + Rect *r1_ptr = &r1; + assert(r1_ptr->area() == 9.0f); + + // member variable pointer + auto tl_mem_ptr = &Rect::tl; // Point Rect::*tl_mem_ptr + + assert((r1.*tl_mem_ptr).x == 1.0f); + + assert((r1_ptr->*tl_mem_ptr).x == 1.0f); + + // member function pointer + auto area_memfn_ptr = &Rect::area; // float (Rect::*area_memfn_ptr)() const + + assert((r1.*area_memfn_ptr)() == 9.0f); + + assert((r1_ptr->*area_memfn_ptr)() == 9.0f); + + // Virtual + Square square{2.0f}; + IShape *shape_ptr = □ + + // virtual member function pointer + auto virt_area_memfn_ptr = &IShape::area; // float (IShape::*virt_area_memfn_ptr)() const + + assert((square.*virt_area_memfn_ptr)() == 4.0f); + + assert((shape_ptr->*virt_area_memfn_ptr)() == 4.0f); +}