Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,16 @@ endforeach()

project(TreeMaker VERSION ${TM_VERSION_MAJOR}.${TM_VERSION_MINOR}.${TM_VERSION_RELEASE} LANGUAGES CXX)

# Set C++ standard
# Set C++20 standard
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

# Add clang-specific flags for C++20
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20")
endif()

# Set output directories
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
Expand Down
28 changes: 14 additions & 14 deletions Source/test/tmArrayTester.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,35 +16,35 @@ Copyright: 2005 Robert J. Lang. All Rights Reserved.
#include "tmArrayIterator.h" // my redefinition of PowerPlant tmArrayIterator

// tmArrayIterator test
void test1(tmArray<const char*>& aList);
void test1(tmArray<const char*>& aList)
void test1(const tmArray<const char*>& aList);
void test1(const tmArray<const char*>& aList)
{
char ch;
tmArrayIterator<const char*> i(aList);
tmArrayIterator i(aList); // Let compiler deduce template argument
const char* c;
while (i.Next(&c)) ch = *c;
while (i.Next(&c)) { /* Testing iterator */ }
}



// for loop test
void test2(tmArray<const char*>& aList);
void test2(tmArray<const char*>& aList)
void test2(const tmArray<const char*>& aList);
void test2(const tmArray<const char*>& aList)
{
char ch;
size_t nmax = aList.size();
for (size_t i = 1; i <= nmax; ++i) *(aList.NthItem(i));
for (size_t i = 1; i <= nmax; ++i) aList.NthItem(i);
}



// for loop with repeated size()
void test2a(tmArray<const char*>& aList);
void test2a(tmArray<const char*>& aList)
void test2a(const tmArray<const char*>& aList);
void test2a(const tmArray<const char*>& aList)
{
char ch;
for (size_t i = 1; i <= aList.size(); ++i) *(aList.NthItem(i));
for (size_t i = 1; i <= aList.size(); ++i) { /* Testing array access */ }
}



// class for test of stored pointers
class Foo {
public:
Expand Down Expand Up @@ -136,7 +136,7 @@ int main(void)
std::cout << "After replace_with(d, a) the list is " << alist << std::endl;

// tmArrayIterator/tmArrayIterator test
tmArrayIterator<const char*> i(alist);
tmArrayIterator i(alist); // Let compiler deduce template argument
const char* dp;
std::cout << "Forward iterator test." << std::endl;
while (i.Next(&dp)) std::cout << "an element is " << dp << std::endl;
Expand Down
201 changes: 150 additions & 51 deletions Source/test/tmDpptrTester.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ Copyright: 2005 Robert J. Lang. All Rights Reserved.
*******************************************************************************/

#include <iostream>
#include <string>
#include <format>

#include "tmDpptr.h"
Expand Down Expand Up @@ -43,33 +42,142 @@ class B;

// Classes A and B hold references to each other.

class A : public virtual tmDpptrTarget
{
public:
A() {cout << "member of class A created" << endl;}
virtual ~A() {cout << "member of class A deleted" << endl;}
class A : public tmDpptrTarget {
public:
// Default constructor
A() : ab() {
cout << "member of class A created" << endl;
}

// Copy constructor with initialization list
A(const A& other) :
tmDpptrTarget(other),
ab(other.ab) {
cout << "member of class A copied" << endl;
}

// Copy assignment operator
A& operator=(const A& other) {
if (this != &other) {
tmDpptrTarget::operator=(other);
ab = other.ab;
cout << "member of class A copy assigned" << endl;
}
return *this;
}

// Move constructor - transfer ownership
A(A&& other) noexcept :
tmDpptrTarget(std::move(other)),
ab(std::move(other.ab)) {
cout << "member of class A moved" << endl;
}

// Move assignment - transfer ownership
A& operator=(A&& other) noexcept {
if (this != &other) {
tmDpptrTarget::operator=(std::move(other));
ab = std::move(other.ab);
cout << "member of class A move assigned" << endl;
}
return *this;
}

~A() override { cout << "member of class A deleted" << endl; }
tmDpptr<B> ab;
};


class B : public virtual tmDpptrTarget
{
public:
B() {cout << "member of class B created" << endl;}
virtual ~B() {cout << "member of class B deleted" << endl;}
class B : public tmDpptrTarget { // Remove virtual
public:
// Default constructor
B() { cout << "member of class B created" << endl; }

// Copy constructor - deep copy the tmDpptr
B(const B& other) : tmDpptrTarget(other) {
ba = other.ba; // tmDpptr has its own copy semantics
cout << "member of class B copied" << endl;
}

// Copy assignment - deep copy the tmDpptr
B& operator=(const B& other) {
if (this != &other) {
tmDpptrTarget::operator=(other);
ba = other.ba; // tmDpptr has its own copy semantics
cout << "member of class B copy assigned" << endl;
}
return *this;
}

// Move constructor - transfer ownership
B(B&& other) noexcept : tmDpptrTarget(std::move(other)), ba(std::move(other.ba)) {
cout << "member of class B moved" << endl;
}

// Move assignment - transfer ownership
B& operator=(B&& other) noexcept {
if (this != &other) {
tmDpptrTarget::operator=(std::move(other));
ba = std::move(other.ba);
cout << "member of class B move assigned" << endl;
}
return *this;
}

~B() override { cout << "member of class B deleted" << endl; }
tmDpptr<A> ba;

void Test() {cout << "test B!" << endl;}
void Test() { cout << "test B!" << endl; }
};


class D : public virtual tmDpptrTarget
{
public:
D(char* aName) : tmDpptrTarget() {std::format_to_n(mName, 20, "{}", aName);
cout << mName << " created" << endl;}
virtual ~D() {cout << mName << " deleted" << endl;}
private:
class D : public tmDpptrTarget {
public:
// Constructor
explicit D(const char* aName) : tmDpptrTarget() {
std::format_to_n(mName, 20, "{}", aName);
cout << mName << " created" << endl;
}

// Copy constructor
D(const D& other) : tmDpptrTarget(other) {
std::copy_n(other.mName, 20, mName);
cout << mName << " copied" << endl;
}

// Copy assignment operator
D& operator=(const D& other) {
if (this != &other) {
tmDpptrTarget::operator=(other);
std::copy_n(other.mName, 20, mName);
cout << mName << " copy assigned" << endl;
}
return *this;
}

// Move constructor
D(D&& other) noexcept : tmDpptrTarget(std::move(other)) {
std::copy_n(other.mName, 20, mName);
other.mName[0] = '\0'; // Clear the source name
cout << mName << " moved" << endl;
}

// Move assignment operator
D& operator=(D&& other) noexcept {
if (this != &other) {
tmDpptrTarget::operator=(std::move(other));
std::copy_n(other.mName, 20, mName);
other.mName[0] = '\0'; // Clear the source name
cout << mName << " move assigned" << endl;
}
return *this;
}

~D() override {
cout << mName << " deleted" << endl;
}

private:
char mName[20];
};

Expand Down Expand Up @@ -105,44 +213,35 @@ int main(void)
cout << "Test of pointer usage:" << endl;

((B*) c)->Test(); // cast to a pointer
(*c).Test(); // dereference
c->Test(); // indirect dereference

c = 0; // Reassigning c removes the last reference to b.
(*c).Test(); // dereference
c->Test(); // arrow operator

cout << endl;
// Use smart pointers instead of raw pointers
auto d1 = std::make_unique<D>("d1");
tmDpptr<D> rd2(std::make_unique<D>("d2").release());

// Now try out a tmDpptrArray that automatically removes objects as they are
// are deleted.
// No need to delete d1, unique_ptr handles cleanup

// Create test objects and populate array
tmDpptrArray<D> rld; // create a list of references

D* d1 = new D(const_cast<char*>("d1")); // create a bunch of objects to put into the list
D* d2 = new D(const_cast<char*>("d2"));
D* d3 = new D(const_cast<char*>("d3"));

tmDpptrTarget* rd1 = d1;
tmDpptrTarget* rd2 = d2;
tmDpptrTarget* rd3 = d3;

rld.push_back(d1); // put them into the list.
rld.push_back(d2);
rld.push_back(d3);
rld.push_back(d1); // also check out effect of multiple references.

// Now we'll delete the original objects one by one and watch as they are
// automatically removed from the list.

// Create objects with clear ownership
std::unique_ptr<D> up1(new D(const_cast<char*>("d1")));
std::unique_ptr<D> up2(new D(const_cast<char*>("d2")));
std::unique_ptr<D> up3(new D(const_cast<char*>("d3")));

// Add to array without transferring ownership
rld.push_back(up1.get());
rld.push_back(up2.get());
rld.push_back(up3.get());
rld.push_back(up1.get()); // test multiple references

cout << "Initially rld has " << rld.size() << " elements." << endl;

delete d1;
cout << "After delete d1 rld has " << rld.size() << " elements." << endl;

delete d2;
cout << "After delete d2 rld has " << rld.size() << " elements." << endl;

delete d3;
cout << "After delete d3 rld has " << rld.size() << " elements." << endl;

// Let smart pointers handle cleanup
up1.reset();
up2.reset();
up3.reset();

// Try it again but this time test the clear() command

Expand Down
1 change: 0 additions & 1 deletion Source/tmModel/tmModel_fwd.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ Copyright: ©2004 Robert J. Lang. All Rights Reserved.
#define _TMMODEL_FWD_H_

// Common header
#include "tmHeader.h"

// All public TreeMaker model classes
class tmPoint;
Expand Down
4 changes: 3 additions & 1 deletion Source/tmModel/tmTreeClasses/tmFacetOwner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ Copyright: ©2004 Robert J. Lang. All Rights Reserved.
*******************************************************************************/

#include "tmFacetOwner.h"
#include "tmModel.h"
#include "tmCrease.h"
#include "tmPoly.h"
#include "tmTree.h"

#ifdef TMDEBUG
#include <fstream>
Expand Down
Loading