diff options
author | Svenson Han Göthel <[email protected]> | 2024-02-25 21:21:12 +0100 |
---|---|---|
committer | Svenson Han Göthel <[email protected]> | 2024-02-25 21:21:12 +0100 |
commit | 46b3474888f9e6a8051fccb4a19d7f2082e62ded (patch) | |
tree | b42ab72e06d95b8ee8c1e5cd391744d3cba88399 /src | |
parent | 7a0938f88c7d4a96e560c701c5c5cad2ca610215 (diff) | |
parent | 79c1d779f4e10d04b158dc66745141550419e1f2 (diff) |
Merge remote-tracking branch 'origin'
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/lesson20_oop_type.cpp | 282 | ||||
-rw-r--r-- | src/lesson21_oop_inherit.cpp | 121 | ||||
-rw-r--r-- | src/lesson22_oop_virtl01.cpp | 112 | ||||
-rw-r--r-- | src/lesson23_oop_virtl02.cpp (renamed from src/lesson25_oop_virtl01.cpp) | 6 | ||||
-rw-r--r-- | src/lesson24_oop_virtl03.cpp | 295 | ||||
-rw-r--r-- | src/lesson40_algo01.cpp | 83 |
7 files changed, 897 insertions, 4 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6df62f9..de97e60 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,7 +3,7 @@ include_directories( ) # These examples use the standard separate compilation -file(GLOB_RECURSE SOURCES_IDIOMATIC_EXAMPLES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "lesson*.cpp") +file(GLOB_RECURSE SOURCES_IDIOMATIC_EXAMPLES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "lesson*.cpp" "example*.cpp") string( REPLACE ".cpp" "" BASENAMES_IDIOMATIC_EXAMPLES "${SOURCES_IDIOMATIC_EXAMPLES}" ) diff --git a/src/lesson20_oop_type.cpp b/src/lesson20_oop_type.cpp new file mode 100644 index 0000000..fef1402 --- /dev/null +++ b/src/lesson20_oop_type.cpp @@ -0,0 +1,282 @@ +//============================================================================ +// Author : Sven Göthel +// Copyright : 2024 Göthel Software e.K. +// License : MIT +// Description : C++ Lesson 2.0 OOP (integer class with operation overloading) +//============================================================================ + +#include <limits> +#include <string> +#include <memory> +#include <cassert> +#include <iostream> + +class sint_t { + private: + int64_t store; + + public: + /** Default constructor (ctor) */ + sint_t() noexcept + : store(0) { } + + /** Copy ctor */ + sint_t(const sint_t& o) noexcept + : store(o.store) { } + + /** Destructor (dtor) */ + ~sint_t() noexcept {} + + /** Explicit conversion ctor: int64_t -> my_int_t */ + explicit sint_t(const int64_t& o) noexcept + : store( o ) { } + + // + // Logical operations + // + + bool is_zero() const noexcept { return 0 == store; } + + /** Explicit bool operator, returns `true` iff this is not zero, otherwise false. */ + explicit operator bool() const noexcept { return !is_zero(); } + + /** Not-bool operator, returns `true` iff this is zero, otherwise false. */ + bool operator !() const noexcept { return is_zero(); } + + // + // Comparison operations + // + + /** Compare function returns 0 if equal, -1 if *this < b and 1 if *this > b. */ + int compare(const sint_t& b) const noexcept { + return store == b.store ? 0 : ( store < b.store ? -1 : 1); + } + + /** Two way comparison operator */ + bool operator==(const sint_t& b) { + return store == b.store; + } + + /** Three way std::strong_ordering comparison operator */ + std::strong_ordering operator<=>(const sint_t& b) { + return store == b.store ? std::strong_ordering::equal : ( store < b.store ? std::strong_ordering::less : std::strong_ordering::greater); + } + + // + // Assignment operations, including arithmetic assignments + // + + /** Assignment */ + sint_t& operator=(const sint_t& r) noexcept { + if( this != &r ) { + store = r.store; + } + return *this; + } + + /** Addition assignment */ + sint_t& operator+=(const sint_t& rhs ) noexcept { + store += rhs.store; + return *this; + } + + /** Subtraction assignment */ + sint_t& operator-=(const sint_t& rhs ) noexcept { + store -= rhs.store; + return *this; + } + + /** Multiplication assignment */ + sint_t& operator*=(const sint_t& rhs ) noexcept { + store *= rhs.store; + return *this; + } + + /** Division assignment */ + sint_t& operator/=(const sint_t& rhs ) noexcept { + store /= rhs.store; + return *this; + } + + /** Remainder assignment */ + sint_t& operator%=(const sint_t& rhs ) noexcept { + store %= rhs.store; + return *this; + } + + // + // Unary arithmetic operations + // + + /** Returns the signum, i.e. `-1` if negative, `0` if zero and `+1` if positive */ + int signum() const noexcept { return 0 == store ? 0 : ( 0 > store ? -1 : +1 ); } + + /** Returns `true` if positive, otherwise `false`. */ + bool positive() const noexcept { return 0 <= store; } + + /** + * Set signum of this integer + * @param new_signum new sign() to set, ignored if this instance is_zero() + */ + void set_sign(const int new_signum) noexcept { + if( !is_zero() && new_signum != 0 ) { + store = std::abs(store) * new_signum; + } + } + + /** Returns opposite of positive(), ignoring signum() `0` */ + int reversed_sign() const noexcept { + if( positive() ) { + return -1; + } else { + return 1; + } + } + + /** Flips the sign of this instance, returns *this */ + sint_t& flip_sign() noexcept { + set_sign(reversed_sign()); + return *this; + } + + /** Unary positive operator, returns new instance of this. */ + sint_t operator+() const noexcept { return sint_t(*this); } + + /** Unary negation operator, returns new negative instance of this. */ + sint_t operator-() const noexcept { return sint_t(*this).flip_sign(); } + + /** Pre-increment unary operation */ + sint_t& operator++() noexcept { ++store; return *this; } + + /** Pre-decrement unary operation */ + sint_t& operator--() noexcept { --store; return *this; } + + /** Post-increment unary operation */ + sint_t operator++(int) noexcept { sint_t x(*this); ++(*this); return x; } + + /** Post-decrement unary operation */ + sint_t operator--(int) noexcept { sint_t x(*this); --(*this); return x; } + + // + // Misc operations + // + + std::string to_string() const noexcept { return std::to_string(store); } +}; + +sint_t operator+(const sint_t& lhs, const sint_t& rhs ) noexcept { + sint_t r(lhs); + r += rhs; + return r; +} + +sint_t operator-(const sint_t& lhs, const sint_t& rhs ) noexcept { + return sint_t(lhs) -= rhs; +} + +sint_t operator*(const sint_t& lhs, const sint_t& rhs ) noexcept { + return sint_t(lhs) *= rhs; +} + +sint_t operator/(const sint_t& lhs, const sint_t& rhs ) noexcept { + return sint_t(lhs) /= rhs; +} + +std::ostream& operator<<(std::ostream& out, const sint_t& v) { + return out << v.to_string(); +} + +int main(int, char*[]) { + sint_t zero(0), ten(10), twenty(20), thirty(30), one(1), two(2); + std::cout << "zero = " << zero << std::endl; + std::cout << "ten = " << ten << std::endl; + std::cout << "twenty = " << twenty << std::endl; + std::cout << "thirty = " << thirty << std::endl; + + // + // Logical operations + // + assert( !zero ); + assert( ten ); + assert( twenty ); + assert( thirty ); + + // + // Comparison operations + // + assert( ten < twenty ); + assert( ten <= ten ); + assert( ten <= twenty ); + assert( ten == ten ); + assert( twenty > ten ); + assert( twenty >= ten ); + assert( twenty >= twenty ); + + // + // Assignment operations, including arithmetic assignments + // + { + sint_t t; t = ten; + assert( t == ten ); + } + { + sint_t t(ten); t += twenty; + assert( t == thirty ); + } + { + sint_t t(ten); t += twenty; + assert( t == thirty ); + } + { + sint_t t(ten); t *= two; + assert( t == twenty ); + } + { + sint_t t(twenty); t /= two; + assert( t == ten ); + } + { + sint_t t(thirty); t %= twenty; + assert( t == ten ); + } + + // + // Unary arithmetic operations + // + sint_t minus_ten(-10), nine(9), eleven(11); + assert( ten == +ten ); + assert( minus_ten == -ten ); + assert( ten == -minus_ten ); + + { + sint_t t(ten); + assert( eleven == ++t ); + assert( eleven == t ); + } + { + sint_t t(ten); + assert( nine == --t ); + assert( nine == t ); + } + { + sint_t t(ten); + assert( ten == t++ ); + assert( eleven == t ); + } + { + sint_t t(ten); + assert( ten == t-- ); + assert( nine == t ); + } + + // + // Binary arithmetic operations + // + assert( one + ten == eleven ); + assert( eleven - one == ten ); + + assert( two * ten == twenty ); + assert( twenty / two == ten ); + + return 0; +} diff --git a/src/lesson21_oop_inherit.cpp b/src/lesson21_oop_inherit.cpp new file mode 100644 index 0000000..2bb4409 --- /dev/null +++ b/src/lesson21_oop_inherit.cpp @@ -0,0 +1,121 @@ +//============================================================================ +// Author : Sven Göthel +// Copyright : 2024 Göthel Software e.K. +// License : MIT +// Description : C++ Lesson 2.1 OOP (simple class inheritance w/o virtual functions) +//============================================================================ + +#include <limits> +#include <string> +#include <memory> +#include <cassert> +#include <iostream> + +class creature_t { + protected: + typedef std::string (*to_string_func_t)(const creature_t&) noexcept; + + private: + to_string_func_t m_to_string; + int m_init_lifetime_left; + int m_lifetime_left; + + protected: + /** Custom constructor (ctor) */ + creature_t(to_string_func_t to_string_func, int lifetime_left) noexcept + : m_to_string(to_string_func), + m_init_lifetime_left(lifetime_left), + m_lifetime_left(lifetime_left) {} + + /** Copy ctor */ + creature_t(const creature_t& o) noexcept = default; + + public: + /** Destructor (dtor) */ + ~creature_t() noexcept = default; + + int total_lifetime() const noexcept { return m_init_lifetime_left; } + int lifetime_left() const noexcept { return m_lifetime_left; } + int age() const noexcept { return total_lifetime() - lifetime_left(); } + bool alive() const noexcept { return lifetime_left() > 0; } + std::string lifesign() const noexcept { return alive() ? "☀" : "✝"; } + + /** Subtract given years of life and return whether there is lifetime left */ + bool tick(int years) noexcept { + if( m_lifetime_left > years ) { + m_lifetime_left -= years; + return true; + } else { + m_lifetime_left = 0; + return false; + } + } + + std::string to_substring() const noexcept { + return "age "+std::to_string(age())+"/"+std::to_string(total_lifetime()); + } + + std::string to_string() const noexcept { + return m_to_string(*this); + } +}; + +std::ostream& operator<<(std::ostream& out, const creature_t& v) { + return out << v.to_string(); +} + +class plant_t : public creature_t { + public: + /** Custom constructor (ctor) */ + plant_t(int lifetime_left) noexcept + : creature_t(to_string_impl, lifetime_left) {} + + /** Copy ctor */ + plant_t(const plant_t& o) noexcept + : creature_t(o) { } + + private: + static std::string to_string_impl(const creature_t& t) noexcept { + return "plant"+t.lifesign()+"["+t.to_substring()+"]"; + } +}; + +class animal_t : public creature_t { + public: + /** Custom constructor (ctor) */ + animal_t(int lifetime_left) noexcept + : creature_t(to_string_impl, lifetime_left) {} + + /** Copy ctor */ + animal_t(const creature_t& o) noexcept + : creature_t(o) { } + + private: + static std::string to_string_impl(const creature_t& t) noexcept { + return "animal"+t.lifesign()+"["+t.to_substring()+"]"; + } +}; + +int main(int, char*[]) { + plant_t p1(3); + animal_t a1(80); + + std::cout << "00.p1 = " << p1 << std::endl; + std::cout << "00.a1 = " << a1 << std::endl; + + creature_t& c1p1 = p1, &c2a1 = a1; + std::cout << "00.c1p1 = " << c1p1 << std::endl; + std::cout << "00.c2a1 = " << c2a1 << std::endl; + + p1.tick(1); + a1.tick(1); + std::cout << "01.p1 = " << p1 << std::endl; + std::cout << "01.a1 = " << a1 << std::endl; + + p1.tick(2); + a1.tick(79); + std::cout << "03.p1 = " << p1 << std::endl; + std::cout << "79.a1 = " << a1 << std::endl; + + return 0; +} diff --git a/src/lesson22_oop_virtl01.cpp b/src/lesson22_oop_virtl01.cpp new file mode 100644 index 0000000..32ec17a --- /dev/null +++ b/src/lesson22_oop_virtl01.cpp @@ -0,0 +1,112 @@ +//============================================================================ +// Author : Sven Göthel +// Copyright : 2024 Göthel Software e.K. +// License : MIT +// Description : C++ Lesson 2.2 OOP (inheritance w/ virtual functions) +//============================================================================ + +#include <limits> +#include <string> +#include <memory> +#include <cassert> +#include <iostream> + +class creature_t { + private: + int m_init_lifetime_left; + int m_lifetime_left; + + protected: + /** Custom constructor (ctor) */ + creature_t(int lifetime_left) noexcept + : m_init_lifetime_left(lifetime_left), + m_lifetime_left(lifetime_left) {} + + /** Copy ctor */ + creature_t(const creature_t& o) noexcept = default; + + public: + /** Virtual destructor (dtor) */ + virtual ~creature_t() noexcept = default; + + int total_lifetime() const noexcept { return m_init_lifetime_left; } + int lifetime_left() const noexcept { return m_lifetime_left; } + int age() const noexcept { return total_lifetime() - lifetime_left(); } + bool alive() const noexcept { return lifetime_left() > 0; } + std::string lifesign() const noexcept { return alive() ? "☀" : "✝"; } + + /** Subtract given years of life and return whether there is lifetime left */ + bool tick(int years) noexcept { + if( m_lifetime_left > years ) { + m_lifetime_left -= years; + return true; + } else { + m_lifetime_left = 0; + return false; + } + } + + /** Fully virtual to_string() method to be implemented in children classes */ + virtual std::string to_string() const noexcept = 0; + + protected: + std::string to_substring() const noexcept { + return "age "+std::to_string(age())+"/"+std::to_string(total_lifetime()); + } +}; + +std::ostream& operator<<(std::ostream& out, const creature_t& v) { + return out << v.to_string(); +} + +class plant_t : public creature_t { + public: + /** Custom constructor (ctor) */ + plant_t(int lifetime_left) noexcept + : creature_t(lifetime_left) {} + + /** Copy ctor */ + plant_t(const plant_t& o) noexcept + : creature_t(o) { } + + /** Virtual to_string() override */ + virtual std::string to_string() const noexcept override { return "plant"+lifesign()+"["+creature_t::to_substring()+"]"; } +}; + +class animal_t : public creature_t { + public: + /** Custom constructor (ctor) */ + animal_t(int lifetime_left) noexcept + : creature_t(lifetime_left) {} + + /** Copy ctor */ + animal_t(const creature_t& o) noexcept + : creature_t(o) { } + + /** Virtual to_string() override */ + virtual std::string to_string() const noexcept override { return "animal"+lifesign()+"["+creature_t::to_substring()+"]"; } +}; + +int main(int, char*[]) { + plant_t p1(3); + animal_t a1(80); + + std::cout << "00.p1 = " << p1 << std::endl; + std::cout << "00.a1 = " << a1 << std::endl; + + creature_t& c1p1 = p1, &c2a1 = a1; + std::cout << "00.c1p1 = " << c1p1 << std::endl; + std::cout << "00.c2a1 = " << c2a1 << std::endl; + + p1.tick(1); + a1.tick(1); + std::cout << "01.p1 = " << p1 << std::endl; + std::cout << "01.a1 = " << a1 << std::endl; + + p1.tick(2); + a1.tick(79); + std::cout << "03.p1 = " << p1 << std::endl; + std::cout << "79.a1 = " << a1 << std::endl; + + return 0; +} diff --git a/src/lesson25_oop_virtl01.cpp b/src/lesson23_oop_virtl02.cpp index d97b8f0..cebe9c9 100644 --- a/src/lesson25_oop_virtl01.cpp +++ b/src/lesson23_oop_virtl02.cpp @@ -1,8 +1,8 @@ //============================================================================ -// Author : Sven Gothel -// Copyright : 2022 Gothel Software e.K. +// Author : Sven Göthel +// Copyright : 2022 Göthel Software e.K. // License : MIT -// Description : C++ Lesson 2.5 OOP (virtual funcation call in ctor/dtor) +// Description : C++ Lesson 2.3 OOP (inheritance w/ virtual function call in ctor/dtor) //============================================================================ #include <iostream> diff --git a/src/lesson24_oop_virtl03.cpp b/src/lesson24_oop_virtl03.cpp new file mode 100644 index 0000000..0d4499c --- /dev/null +++ b/src/lesson24_oop_virtl03.cpp @@ -0,0 +1,295 @@ +//============================================================================ +// Author : Sven Göthel +// Copyright : 2024 Göthel Software e.K. +// License : MIT +// Description : C++ Lesson 2.4 OOP (inheritance w/ virtual lifecycle managment) +//============================================================================ + +#include <limits> +#include <string> +#include <memory> +#include <vector> +#include <atomic> +#include <cassert> +#include <iostream> + +class creature_t { + private: + static std::atomic_uint64_t next_instance; + uint64_t m_id; + int m_init_lifetime_left; + int m_init_childs_left; + int m_lifetime_left; + int m_childs_left; + + protected: + /** Custom constructor (ctor) */ + creature_t(int lifetime_left, int childs_left) noexcept + : m_id(++next_instance), + m_init_lifetime_left(lifetime_left), m_init_childs_left(childs_left), + m_lifetime_left(lifetime_left), m_childs_left(childs_left) {} + + /** Copy ctor, actually creating a new life (asexual) w/ a new instance id() */ + creature_t(const creature_t& o) noexcept + : m_id(++next_instance), + m_init_lifetime_left(o.m_init_lifetime_left), m_init_childs_left(o.m_init_childs_left), + m_lifetime_left(o.m_init_lifetime_left), m_childs_left(o.m_init_childs_left) {} + + /** Copy ctor, actually creating a new life (sexual) w/ a new instance id() */ + creature_t(const creature_t& a, const creature_t& b) noexcept + : m_id(++next_instance), + m_init_lifetime_left((a.m_init_lifetime_left+b.m_init_lifetime_left)/2), + m_init_childs_left((a.m_init_childs_left+b.m_init_childs_left)/2), + m_lifetime_left((a.m_init_lifetime_left+b.m_init_lifetime_left)/2), + m_childs_left((a.m_init_childs_left+b.m_init_childs_left)/2) {} + + /** Move ctor */ + creature_t(creature_t&& o) noexcept + : m_id(o.m_id), m_init_lifetime_left(o.m_lifetime_left), m_init_childs_left(o.m_childs_left), + m_lifetime_left(o.m_lifetime_left), m_childs_left(o.m_childs_left) + { + o.m_id = 0; + o.m_childs_left = 0; + o.m_lifetime_left = 0; + } + + public: + /** Virtual destructor (dtor) */ + virtual ~creature_t() noexcept = default; + + /** reproduction type */ + enum class repro_t { + /** asexual reproduction only */ + asexual, + /** sexual reproduction only */ + sexual, + /** asexual and sexual reproduction */ + dual + }; + /** Returns the reproduction type */ + virtual repro_t repro_type() const noexcept = 0; + + protected: + /** Fully virtual copy-ctor function (asexual) on this super class */ + virtual std::shared_ptr<creature_t> new_instance() noexcept = 0; + + /** Fully virtual copy-ctor function (sexual) on this super class */ + virtual std::shared_ptr<creature_t> new_instance(const creature_t& o) noexcept = 0; + + public: + /** create one offspring (asexual) if childs_left() > 0 and repro_type() is not repro_t::sexual, otherwise returns nullptr. */ + std::shared_ptr<creature_t> procreate() noexcept { + if( repro_t::sexual != repro_type() && + m_childs_left > 0 ) + { + --m_childs_left; + return new_instance(); + } else { + return nullptr; + } + } + + /** create one offspring (sexual) if childs_left() > 0 and repro_type() is not repro_t::asexual, otherwise returns nullptr. */ + std::shared_ptr<creature_t> procreate(creature_t& o) noexcept { + if( repro_t::asexual != repro_type() && + m_childs_left > 0 && o.childs_left() > 0 ) + { + --m_childs_left; + --o.m_childs_left; + return new_instance(o); + } else { + return nullptr; + } + } + + /** returns the unique creature id */ + uint64_t id() const noexcept { return m_id; } + + int total_lifetime() const noexcept { return m_init_lifetime_left; } + int lifetime_left() const noexcept { return m_lifetime_left; } + int age() const noexcept { return total_lifetime() - lifetime_left(); } + bool alive() const noexcept { return lifetime_left() > 0; } + std::string lifesign() const noexcept { return alive() ? "☀" : "✝"; } + + int total_childs() const noexcept { return m_init_childs_left; } + int childs_left() const noexcept { return m_childs_left; } + int children() const noexcept { return total_childs() - childs_left(); } + + /** Subtract given years of life and return whether there is lifetime left */ + bool tick(int years) noexcept { + if( m_lifetime_left > years ) { + m_lifetime_left -= years; + return true; + } else { + m_lifetime_left = 0; + return false; + } + } + + /** Fully virtual to_string() method to be implemented in children classes */ + virtual std::string to_string() const noexcept = 0; + + protected: + std::string to_substring() const noexcept { + return "id "+std::to_string(id())+", age "+std::to_string(age())+"/"+std::to_string(total_lifetime())+", childs "+std::to_string(children())+"/"+std::to_string(total_childs()); + } +}; +std::atomic_uint64_t creature_t::next_instance; + +typedef std::shared_ptr<creature_t> shared_creature_t; + +std::ostream& operator<<(std::ostream& out, const creature_t& v) { + return out << v.to_string(); +} + +/** + * A plant_t creature_t type supporting both, asexual and sexual procreation. + */ +class plant_t : public creature_t { + public: + /** Custom constructor (ctor) */ + plant_t(int lifetime_left, int childs_left) noexcept + : creature_t(lifetime_left, childs_left) {} + + /** Move ctor */ + plant_t(plant_t&& o) noexcept + : creature_t(std::move(o)) {} + + virtual repro_t repro_type() const noexcept override { return repro_t::dual; } + + /** Virtual to_string() override */ + virtual std::string to_string() const noexcept override { return "plant"+lifesign()+"["+creature_t::to_substring()+"]"; } + + protected: + /** Copy ctor, actually creating a new life (asexual) w/ a new instance id() */ + plant_t(const plant_t& o) noexcept + : creature_t(o) { } + + /** Copy ctor, actually creating a new life (sexual) w/ a new instance id() */ + plant_t(const plant_t& a, const plant_t& b) noexcept + : creature_t(a, b) { } + + /** Virtual new_copy() (asexual) override */ + virtual std::shared_ptr<creature_t> new_instance() noexcept override { + return std::shared_ptr<plant_t>( new plant_t(*this) ); + } + + /** Virtual new_instance() (sexual) override */ + virtual std::shared_ptr<creature_t> new_instance(const creature_t& o) noexcept override { + return std::shared_ptr<plant_t>( new plant_t(*this, *static_cast<const plant_t*>(&o)) ); + } +}; + +/** + * An animal_t creature_t type supporting sexual procreation only + */ +class animal_t : public creature_t { + public: + /** Custom constructor (ctor) */ + animal_t(int lifetime_left, int childs_left) noexcept + : creature_t(lifetime_left, childs_left) {} + + /** Move ctor */ + animal_t(animal_t&& o) noexcept + : creature_t(std::move(o)) {} + + virtual repro_t repro_type() const noexcept override { return repro_t::sexual; } + + /** Virtual to_string() override */ + virtual std::string to_string() const noexcept override { return "animal"+lifesign()+"["+creature_t::to_substring()+"]"; } + + protected: + /** Copy ctor, actually creating a new life (asexual) w/ a new instance id() */ + animal_t(const animal_t& o) noexcept + : creature_t(o) { } + + /** Copy ctor, actually creating a new life (sexual) w/ a new instance id() */ + animal_t(const animal_t& a, const animal_t& b) noexcept + : creature_t(a, b) { } + + /** Virtual new_copy() (asexual) override - returns nullptr */ + virtual std::shared_ptr<creature_t> new_instance() noexcept override { + return std::shared_ptr<animal_t>(); + } + /** Virtual new_instance() (sexual) override */ + virtual std::shared_ptr<creature_t> new_instance(const creature_t& o) noexcept override { + return std::shared_ptr<animal_t>( new animal_t(*this, *static_cast<const animal_t*>(&o)) ); + } +}; + +int main(int, char*[]) { + plant_t p1(3, 1000); + animal_t a1(80, 6), a2(40, 3); + + std::cout << "00.p1 = " << p1 << std::endl; + std::cout << "00.a1 = " << a1 << std::endl; + std::cout << "00.a2 = " << a2 << std::endl; + + creature_t& c1p1 = p1, &c2a1 = a1; + std::cout << "00.c1p1 = " << c1p1 << std::endl; + std::cout << "00.c2a1 = " << c2a1 << std::endl; + + p1.tick(1); + a1.tick(1); + a2.tick(2); + std::cout << "01.p1 = " << p1 << std::endl; + std::cout << "01.a1 = " << a1 << std::endl; + std::cout << "01.a2 = " << a2 << std::endl; + + shared_creature_t p2 = p1.procreate(); + assert( nullptr != p2 ); + std::cout << "00.p2 = " << *p2 << std::endl; + { + // casting shared_ptr<super-class> to shared_ptr<sub-class> is possible, if you must + std::shared_ptr<plant_t> p2_plant = std::static_pointer_cast<plant_t>( p2 ); + assert( nullptr != p2_plant ); + } + { + shared_creature_t a12 = a1.procreate(); // only sexual procreation supported for this animal_t + assert( nullptr == a12 ); + } + shared_creature_t a12 = a1.procreate(a2); + assert( nullptr != a12 ); + std::cout << "00.a12 = " << *a12 << std::endl; + + p1.tick(2); + a1.tick(79); + std::cout << "03.p1 = " << p1 << std::endl; + std::cout << "79.a1 = " << a1 << std::endl; + + p2->tick(3); + std::cout << "03.p2 = " << *p2 << std::endl; + { + std::vector<shared_creature_t> a12childs; + { + shared_creature_t c; + while( nullptr != ( c = a12->procreate(a1) ) ) { + a12childs.push_back(c); + } + assert( 0 < a12childs.size() ); + } + std::cout << "00.a12 = " << *a12 << ", created "+std::to_string(a12childs.size()) << std::endl; + for(shared_creature_t c : a12childs) { + std::cout << "00.a12.c = " << *c << std::endl; + } + a12->tick(60); + std::cout << "60.a12 = " << *a12 << std::endl; + } + + { + // animal_t a3(80, 4); + // animal_t a3b(a3); // error, copy-ctor is non-public + } + { + animal_t a3(80, 4); + animal_t a3b(std::move(a3)); + std::cout << "00.a3 = " << a3 << " -> " << a3b << std::endl; + } + { + animal_t a3(80, 4); + animal_t a3b = std::move(a3); + std::cout << "00.a3 = " << a3 << " -> " << a3b << std::endl; + } + + return 0; +} diff --git a/src/lesson40_algo01.cpp b/src/lesson40_algo01.cpp new file mode 100644 index 0000000..a701166 --- /dev/null +++ b/src/lesson40_algo01.cpp @@ -0,0 +1,83 @@ +//============================================================================ +// Author : Svenson Han Göthel and Sven Göthel +// Version : 0.1 +// Copyright : MIT +// Description : C++ Lesson 4.0 Simple algorithms using C++ +//============================================================================ + +#include <cstdio> +#include <iostream> +#include <cmath> +#include <vector> + +#include <limits> + +/** + * Lesson 4.0 + * + * Implementing simple algorithms + */ + +int binary_search(const std::vector<int>& array, int target) { + int l = 0; + int h = array.size()-1; + int i; + while( l <= h ) { + i = ( l + h ) / 2; + if ( array[i] < target ) { + l = i + 1; + } else if ( array[i] > target ) { + h = i - 1; + } else { + return i; + } + } + return -1; +} + +bool test_binsearch(const std::vector<int>& array, int target, int exp, int& has) { + has = binary_search(array, target); + if( exp != has ) { + printf("Error-1: has %d != exp %d\n", has, exp); + return false; + } else { + return true; + } +} + +int main(int, const char**) { + int error_counter = 0; + { + std::vector<int> array = { 1, 3, 4, 5, 6, 9, 11 }; + for(size_t i=0; i < array.size(); ++i) { + const int target = array[i]; + int idx; + if( !test_binsearch(array, target, i, idx) ) { + std::cout << "ERROR: array[" << i << "] = " << target << " found at " << idx << std::endl; + ++error_counter; + } else { + std::cout << "OK : array[" << i << "] = " << target << " found at " << idx << std::endl; + } + } + { + std::vector<int> targets2 = { 0, 2, 7, 8, 10, 12 }; + for(size_t i=0; i < targets2.size(); ++i) { + const int target = targets2[i]; + int idx; + if( !test_binsearch(array, target, -1, idx) ) { + std::cout << "ERROR: " << target << " found at " << idx << std::endl; + ++error_counter; + } else { + std::cout << "OK : " << target << " not found, idx " << idx << std::endl; + } + } + } + } + if( 0 == error_counter ) { + std::cout << "No error" << std::endl; + return 0; + } else { + std::cout << error_counter << " error(s)" << std::endl; + return 1; + } +} |