diff --git a/ex0.2/gen_rand_explicit.py b/ex0.2/gen_rand_explicit.py new file mode 100644 index 0000000..f47ca66 --- /dev/null +++ b/ex0.2/gen_rand_explicit.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python3 + +import numpy as np +import sys + +N = 1e6 + +if len(sys.argv) > 1: + N = float(sys.argv[1]) + +for _ in range(int(N)): + print( np.random.rand(1) ) diff --git a/ex0.2/results.txt b/ex0.2/results.txt index 485f30a..2061083 100644 --- a/ex0.2/results.txt +++ b/ex0.2/results.txt @@ -1,4 +1,10 @@ -Running `time ./gen_rand.py "1e9"` gives +Running `time ./gen_rand.py "1e6"` gives -real 0m13.803s -user 0m8.874s +real 0m0.237s +user 0m0.160s + +Contrast this to the following: +Running `time ./gen_rand_explicit.py "1e6"` gives + +real 2m11.564s +user 2m1.950s diff --git a/ex1.2/string_analyzer.cpp b/ex1.2/string_analyzer.cpp index c34cb86..6a22b6f 100644 --- a/ex1.2/string_analyzer.cpp +++ b/ex1.2/string_analyzer.cpp @@ -19,15 +19,15 @@ int main() { unsigned int chars_capital = 0, chars_lower = 0, chars_digits = 0, chars_other = 0; while ( *ptr != 0 ) { - if ( *ptr >= int('A') && *ptr <= int('Z') ) + if ( *ptr >= 'A' && *ptr <= 'Z' ) { ++chars_capital; } - else if ( *ptr >= int('a') && *ptr <= int('z') ) + else if ( *ptr >= 'a' && *ptr <= 'z' ) { ++chars_lower; } - else if ( *ptr >= int('0') && *ptr <= int('9') ) + else if ( *ptr >= '0' && *ptr <= '9' ) { ++chars_digits; } diff --git a/ex1.3/join_strings.cpp b/ex1.3/join_strings.cpp index 03af02b..ace11aa 100644 --- a/ex1.3/join_strings.cpp +++ b/ex1.3/join_strings.cpp @@ -39,7 +39,9 @@ char* join(const char* str1 , const char* str2) char* joinb(const char* str1 , const char* str2) { - int size = strlen(str1) + strlen(str2) + 1; + // size should be 2 more than required for the strlens to + // incorporate the space and the null byte + int size = strlen(str1) + strlen(str2) + 2; char* new_str = new char[size]; *new_str = 0; diff --git a/ex1.4/leak_memory.cpp b/ex1.4/leak_memory.cpp index 8d76c6a..9fd26fd 100644 --- a/ex1.4/leak_memory.cpp +++ b/ex1.4/leak_memory.cpp @@ -15,12 +15,25 @@ #define MEMORY_SIZE_IN_CHARS G +void make_throwaway_ptrs(int leak_size ) { + for ( int i = 0; i < leak_size ; i++) + { + char* throwaway_ptr = new char; + } + + // oops, we are not returning the pointers + // this means it goes out of scope when the function ends +} + + int main() { - char* throwaway_ptr = new char[MEMORY_SIZE_IN_CHARS]; + make_throwaway_ptrs(MEMORY_SIZE_IN_CHARS); std::cout << "We leaked " << MEMORY_SIZE_IN_CHARS * sizeof " " << " bits" << std::endl; + + std::cout << "Ready to kill the process? (press Enter)" << std::endl; + std::cin.ignore(); return 0; } - diff --git a/ex1.5/base32.cpp b/ex1.5/base32.cpp index a14c009..30442f5 100644 --- a/ex1.5/base32.cpp +++ b/ex1.5/base32.cpp @@ -23,10 +23,10 @@ #include #include -#define VERBOSE false +#define VERBOSE true -char b32_lookup_table[] = "ABCDEFGHIJKLMNOPQRSTUV"; -int base = 8; +char b32_lookup_table[] = "0123456789ABCDEFGHIJKLMNOPQRSTUV"; +int base = 32; int main() { //a @@ -75,7 +75,7 @@ int main() { digits[digit_num] = number & lsb_bitmask; // Shift off the bits we have put in to the array - number = ( number >> bits_in_char ); + number >>= bits_in_char; ++digit_num; } @@ -91,14 +91,7 @@ int main() { // Loop the other way so the first digit we get out is MSB while ( digit_num >= 0 ) { - if ( digits[digit_num] < 10 ) - { - std::cout << digits[digit_num]; - } - else - { - std::cout << b32_lookup_table[digits[digit_num] - 10]; - } + std::cout << b32_lookup_table[digits[digit_num]]; digit_num--; } diff --git a/ex10/ThreadPool.cc b/ex10/ThreadPool.cc new file mode 100644 index 0000000..674ede4 --- /dev/null +++ b/ex10/ThreadPool.cc @@ -0,0 +1,77 @@ +// ThreadPool.cc +#include "threadpool.hh" +#include "shared_queue.hh" + +#include +#include +#include +#include + +void producer( const int id, SharedQueue& q, int max_t, int max_n ) +{ + std::random_device d; + std::mt19937 mt(d()); + std::uniform_int_distribution<> distr(0., max_t); + + std::cout << " -- Starting Producer " << id << " (max_t: " << max_t << " max_n: " << max_n << ")" << std::endl; + for ( int n = 0; n < max_n ; ++n ) + { + std::cout << " -- Producer " << id << "; n = " << n << std::endl; + + int l = distr(mt); + std::this_thread::sleep_for(std::chrono::milliseconds(l)); + + // Lock q so we can push a new element + std::unique_lock lock(*q.mutex()); + q.queue()->push(l); + + std::cout << " -- Producer " << id << " pushed = " << l << std::endl; + + // Notify one of the consumers + q.cv()->notify_one(); + + } + + + std::cout << "Exiting Producer " << id << std::endl; +} +void consumer( const int id, SharedQueue& q, int max_t, int max_n ) +{ + const int time_out = 5 ;// seconds + int b = 0; + + std::cout << " -- Starting Consumer " << id << " (max_t: " << max_t << " max_n: " << max_n << ")" << std::endl; + for ( int n = 0; n < max_n ; n++ ) + { + std::cout << " -- Consumer " << id << "; n = " << n << std::endl; + { // Scope the lock of the queue + std::unique_lock q_lock(*q.mutex()); + + while ( q.queue()->empty() ) { + // Wait until we get a signal from the condition variable + // or we reach a timeout + if ( q.cv()->wait_for(q_lock, std::chrono::seconds(time_out)) == std::cv_status::timeout ) + { + // We reached the timeout + std::cout << " -- Consumer " << id << " timed out (" << time_out << "s)" << std::endl; + + // this consumer does nothing after stopping the loop + // so we can return to break the loops + return; + } + } + + // Get a value and pop it off + b = q.queue()->front(); + q.queue()->pop(); + } + + std::cout << " -- Consumer " << id << " read: " << b << std::endl; + + // Slow down this thread to have a race between the consumers and the producers + // This only works after we have successfully read an int + std::this_thread::sleep_for(std::chrono::milliseconds(max_t)); + } + + std::cout << "Exiting Consumer " << id << std::endl; +} diff --git a/ex10/main.cpp b/ex10/main.cpp new file mode 100644 index 0000000..f42467d --- /dev/null +++ b/ex10/main.cpp @@ -0,0 +1,24 @@ +#include "shared_queue.hh" +#include "threadpool.hh" + +#include +#include +int main() { + + std::cout << "Set up ThreadPool" << std::endl; + ThreadPool tp; + + std::cout << "Add Producer" << std::endl; + tp.addProducer(); + + std::cout << "Add Consumers" << std::endl; + tp.addConsumer(); + tp.addConsumer(); + + std::cout << "Run" << std::endl; + tp.run(); + + std::cout << "Finishing up" << std::endl; + + return 0; +} diff --git a/ex10/main.py b/ex10/main.py new file mode 100644 index 0000000..e4214a0 --- /dev/null +++ b/ex10/main.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 + +import ThreadPool + +if __name__ == "__main__": + print(dir(ThreadPool)) + tp = ThreadPool.ThreadPool() + + print("Creating Consumers") + tp.addConsumer( 2000, 20 ) + tp.addConsumer( 2000, 10 ) + + + print("Create Producers") + tp.addProducer( 4000, 5 ) + + print("Run all Threads") + tp.run() + + print("End of Program") diff --git a/ex10/makefile b/ex10/makefile new file mode 100644 index 0000000..52c7362 --- /dev/null +++ b/ex10/makefile @@ -0,0 +1,8 @@ +main: + g++ -pthread ThreadPool.cc main.cpp + +threadpool: + g++ -pthread -D ENABLE_PYBIND=1 -O3 -Wall -shared -std=c++11 -fPIC `python3 -m pybind11 --includes` ThreadPool.cc -o ThreadPool`python3-config --extension-suffix` + +clean: + rm -rf *.so __pycache__ diff --git a/ex10/shared_queue.hh b/ex10/shared_queue.hh new file mode 100644 index 0000000..143f802 --- /dev/null +++ b/ex10/shared_queue.hh @@ -0,0 +1,39 @@ +// Shared_Queue.hh +#include +#include +#include +#include + +#ifndef SHARED_QUEUE_HH +#define SHARED_QUEUE_HH +template +class SharedQueue +{ + public: + SharedQueue() : + _q(), + _q_mutex(), + _q_cv() + {}; + + SharedQueue( const SharedQueue& other ) + { + std::cout << "Copy Constructor SharedQueue" << std::endl; + // (Read)Lock the other queue for copying + std::unique_lock other_lock(other._q_mutex); + _q = other._q; + } + + std::queue * queue() { return& _q; } + std::mutex * mutex() { return& _q_mutex; } + std::condition_variable * cv() { return& _q_cv; } + + private: + // Queue + std::queue _q; + + // Synchronisation + std::mutex _q_mutex; + std::condition_variable _q_cv; +}; +#endif diff --git a/ex10/threadpool.hh b/ex10/threadpool.hh new file mode 100644 index 0000000..b823d79 --- /dev/null +++ b/ex10/threadpool.hh @@ -0,0 +1,79 @@ +// ThreadPool.hh +#include "shared_queue.hh" + +#include +#include + +#ifndef THREAD_POOL_H +#define THREAD_POOL_H + +// Implementations for producers and consumers +void producer( const int id, SharedQueue& _q, int max_t, int max_n ); +void consumer( const int id, SharedQueue& _q, int max_t, int max_n ); + +class ThreadPool +{ + public: + ThreadPool() : + _q(), + _consumers(), + _producers() + {}; + void addProducer( int max_t = 3000, int max_n = 10) + { + std::thread * tp = new std::thread( producer, _producers.size(), std::ref(_q), max_t, max_n ); + + _producers.push_back(tp); + + } + + void addConsumer( int max_t = 2000, int max_n = 10) + { + std::thread * tp = new std::thread( consumer, _consumers.size(), std::ref(_q), max_t, max_n ); + + _consumers.push_back(tp); + } + + void run() + { + // join all producers + for ( int i = 0; i < _producers.size() ; i++ ) + { + (*_producers[i]).join(); + } + + // join all consumers + for ( int i = 0; i < _consumers.size() ; i++ ) + { + (*_consumers[i]).join(); + } + } + + + private: + // Consumer and Producers threads + std::vector _consumers; + std::vector _producers; + + // queue + SharedQueue _q; +}; + +#if ENABLE_PYBIND +/* + * Define Python access + */ +#include + +namespace py = pybind11; + +PYBIND11_MODULE(ThreadPool, tp) +{ + py::class_( tp, "ThreadPool") + .def(py::init()) + .def("addProducer", &ThreadPool::addProducer, "Add a new Producer to the Pool") + .def("addConsumer", &ThreadPool::addConsumer, "Add a new Consumer to the Pool") + .def("run", &ThreadPool::run, "Run all registered Producers and Consumers"); +} +#endif +#endif diff --git a/ex2.1/bubble_sort_int.cpp b/ex2.1/bubble_sort_int.cpp index 0c83ce5..077ec29 100644 --- a/ex2.1/bubble_sort_int.cpp +++ b/ex2.1/bubble_sort_int.cpp @@ -83,8 +83,8 @@ void orderptr( int* a, int* b ) { return; } - int* tmp = a; - a = b; - b = tmp; + int tmp = *a; + *a = *b; + *b = tmp; } #endif diff --git a/ex2.1/bubble_sort_str.cpp b/ex2.1/bubble_sort_str.cpp index b6b700a..d4b5884 100644 --- a/ex2.1/bubble_sort_str.cpp +++ b/ex2.1/bubble_sort_str.cpp @@ -15,9 +15,9 @@ void sort( const char** A, const int size ); #if !USE_PTR -void order( const char* a, const char* b ); +void order( const char* &a, const char* &b ); #else -void orderptr( const char* &a, const char* &b ); +void orderptr( const char* *a, const char* *b ); #endif @@ -78,34 +78,14 @@ void sort( const char** A, const int size ) { #if !USE_PTR order( A[ i ], A[ j ] ); #else - orderptr( A[ i ], A[ j ] ); + orderptr( &A[ i ], &A[ j ] ); #endif } } } #if !USE_PTR -void order( const char* a, const char* b ) { - #if VERBOSE - std::cout << "Order: " << a << std::endl; - #endif - // b is greater or equal to a, do nothing - if ( strcmp(a, b) > 0) { - #if VERBOSE - std::cout << "Ordering OK" << std::endl; - #endif - return; - } - #if VERBOSE - std::cout << "Ordering ToDo" << std::endl; - #endif - - const char* tmp = a; - a = b; - b = tmp; -} -#else -void orderptr( const char* &a, const char* &b ) { +void order( const char* &a, const char* &b ) { #if VERBOSE std::cout << "Order: " << a << ", " << b << std::endl; #endif @@ -123,4 +103,24 @@ void orderptr( const char* &a, const char* &b ) { a = b; b = tmp; } +#else +void orderptr( const char* *a, const char* *b ) { + #if VERBOSE + std::cout << "Order: " << a << std::endl; + #endif + // b is greater or equal to a, do nothing + if ( strcmp(*a, *b) > 0) { + #if VERBOSE + std::cout << "Ordering OK" << std::endl; + #endif + return; + } + #if VERBOSE + std::cout << "Ordering ToDo" << std::endl; + #endif + + const char* tmp = *a; + *a = *b; + *b = tmp; +} #endif diff --git a/ex2.2/overloading.cpp b/ex2.2/overloading.cpp index 0937450..a259d86 100644 --- a/ex2.2/overloading.cpp +++ b/ex2.2/overloading.cpp @@ -3,12 +3,14 @@ * * generalisation of type is possible * => not writing an int implementation means always use the double - * => => even when to ints are supplied, they are generalised to doubles + * => => even when two ints are supplied, they are generalised to doubles */ #include -//int min( int a, int b ); +int min( int a, int b ); +double min( double a, int b ); +double min( int a, double b ); double min( double a, double b ); int min( int a[], int size); @@ -27,15 +29,30 @@ int main() { std::cout << "min( 3.12345, 4 ) = " << min(3.12345, 4) << std::endl; + std::cout << "min( 4, 3.12345 ) = " << min(4, 3.12345) << std::endl; return 0; } -//int min( int a, int b ) { -// if ( a < b ) { -// return a; -// } -// return b; -//} +int min( int a, int b ) { + if ( a < b ) { + return a; + } + return b; +} + +double min( double a, int b ) { + if ( a < b ) { + return a; + } + return b; +} + +double min( int a, double b ) { + if ( a < b ) { + return a; + } + return b; +} double min( double a, double b ) { if ( a < b ) { @@ -53,3 +70,5 @@ int min( int a[], int size ) { return m; } + +// Fix interchangeabiliy of doubles and ints diff --git a/ex2.5/ndim.cpp b/ex2.5/ndim.cpp index 575da19..1236a07 100644 --- a/ex2.5/ndim.cpp +++ b/ex2.5/ndim.cpp @@ -37,7 +37,6 @@ int main() { - double * nvec = multiply( ivec, Nx, mtx ); @@ -49,6 +48,17 @@ int main() { } std::cout << "]" << std::endl; delete nvec; + + // print the matrix as it is stored in memory + std::cout << "In-Memory Matrix = "; + std::cout << "[" << std::endl; + + for ( int i = 0; i < Nx*Y_SIZE; i++ ){ + std::cout << mtx[0][i] << ", "; + } + std::cout << std::endl; + std::cout << "]" << std::endl; + } diff --git a/ex3.2/Stack.cc b/ex3.2/Stack.cc index 71dda3f..71a1c92 100644 --- a/ex3.2/Stack.cc +++ b/ex3.2/Stack.cc @@ -4,8 +4,6 @@ void Stack::push(double c) { if (full()) { - std::cout << "Stack::push() Error: stack is full" << std::endl ; - grow( DELTA ); } s[count++] = c ; @@ -34,7 +32,10 @@ void Stack::init( int in_size ) { } void Stack::grow( int delta ) { std::cout << "Growing by " << delta << std::endl; - double* newbuf = new double[ bufsize + delta ]; + + int newbufsize = bufsize + delta; + + double* newbuf = new double[ newbufsize ]; // Copy elements for ( int i=0; i < count ; i++ ) @@ -47,4 +48,8 @@ void Stack::grow( int delta ) { // Assign pointer s = newbuf; + + // Update bufsize + bufsize = newbufsize; + } diff --git a/ex3.2/main.cpp b/ex3.2/main.cpp index 0f2840c..6a41b03 100644 --- a/ex3.2/main.cpp +++ b/ex3.2/main.cpp @@ -7,7 +7,7 @@ using namespace std ; int main() { - Stack s(10) ;// initialize Stack + Stack s(5) ;// initialize Stack // Write doubles into Stack int i ; @@ -17,7 +17,7 @@ int main() { } // Count doubles in fifo - cout << s.nitems() << " value in stack" << endl ; + cout << s.nitems() << " values in Stack" << endl ; cout << "Inspect the FIFO" << endl; s.inspect(); @@ -26,7 +26,7 @@ int main() { // Read doubles back from fifo while (!s.empty()) { double val = s.pop() ; - cout << "popping value " << val << " from stack" << endl ; + cout << "popping value " << val << " from Stack" << endl ; } cout << "Inspect the FIFO" << endl; diff --git a/ex4.1/Dialer.hh b/ex4.1/Dialer.hh index 2aeaf04..528fffe 100644 --- a/ex4.1/Dialer.hh +++ b/ex4.1/Dialer.hh @@ -4,6 +4,8 @@ #include "Button.hh" +#define DEFAULT_NUMBER_BUTTONS 12 + class Dialer { public: @@ -14,7 +16,11 @@ public: Dialer(const Dialer& other) { std::cout << "Dialer Copy Constructor " << this << std::endl ; - init(); + init(other.buttons_size); + // Copy the buttons + for ( int i = 0; i < other.buttons_size; i++ ) { + buttons[i] = other.buttons[i]; + } } ~Dialer() { std::cout << "Dialer Destructor " << this << std::endl ; @@ -25,10 +31,16 @@ private: void init() { - buttons = new Button[12]; + this->init( DEFAULT_NUMBER_BUTTONS ); + } + void init( int num_buttons ) + { + buttons_size = num_buttons; + buttons = new Button[buttons_size]; } Button* buttons ; + int buttons_size; } ; diff --git a/ex4.1/Handset.hh b/ex4.1/Handset.hh index c0cd9ea..9e38063 100644 --- a/ex4.1/Handset.hh +++ b/ex4.1/Handset.hh @@ -10,7 +10,13 @@ class Handset { public: Handset() { std::cout << "Handset Constructor " << this << std::endl ; } - Handset(const Handset&) { std::cout << "Handset Copy Constructor " << this << std::endl ; } + Handset(const Handset& h) : + mouthpiece( h.mouthpiece ), + earpiece( h.earpiece ), + cable( h.cable ) + { + std::cout << "Handset Copy Constructor " << this << std::endl ; + } ~Handset() { std::cout << "Handset Destructor " << this << std::endl ; } private: diff --git a/ex4.1/Housing.hh b/ex4.1/Housing.hh index 4d1334b..0423357 100644 --- a/ex4.1/Housing.hh +++ b/ex4.1/Housing.hh @@ -9,7 +9,12 @@ class Housing { public: Housing() { std::cout << "Housing Constructor " << this << std::endl ; } - Housing(const Housing&) { std::cout << "Housing Copy Constructor " << this << std::endl ; } + Housing(const Housing& h) : + chassis( h.chassis ), + shell( h.shell ) + { + std::cout << "Housing Copy Constructor " << this << std::endl ; + } ~Housing() { std::cout << "Housing Destructor " << this << std::endl ; } private: diff --git a/ex4.1/Telephone.hh b/ex4.1/Telephone.hh index 371d826..4d2e51a 100644 --- a/ex4.1/Telephone.hh +++ b/ex4.1/Telephone.hh @@ -9,9 +9,19 @@ class Telephone { public: - Telephone() { std::cout << "Telephone Constructor " << this << std::endl ; } - Telephone(const Telephone& t ) { std::cout << "Telephone Copy Constructor " << this << std::endl ; } - ~Telephone() { std::cout << "Telephone Destructor " << this << std::endl ; } + Telephone() { + std::cout << "Telephone Constructor " << this << std::endl; + } + Telephone(const Telephone& t ) : + cable( t.cable ), + housing( t.housing ), + dialer( t.dialer ), + handset( t.handset ) { + std::cout << "Telephone Copy Constructor " << this << std::endl; + } + ~Telephone() { + std::cout << "Telephone Destructor " << this << std::endl; + } private: diff --git a/ex4.1/main.cpp b/ex4.1/main.cpp index 1d527dc..74de493 100644 --- a/ex4.1/main.cpp +++ b/ex4.1/main.cpp @@ -3,5 +3,14 @@ int main(){ Telephone t; + std::cout << std::endl; + std::cout << "Cloning the Telephone object" << std::endl; + std::cout << std::endl; + Telephone t2 = t; + + std::cout << std::endl; + std::cout << "Destructing all objects" << std::endl; + std::cout << std::endl; + } diff --git a/ex4.2/CaloCell.cc b/ex4.2/CaloCell.cc deleted file mode 100644 index b4e4f57..0000000 --- a/ex4.2/CaloCell.cc +++ /dev/null @@ -1,18 +0,0 @@ -//CaloGrid.cc -#include -#include "CaloGrid.hh" - -CaloCell* CaloGrid::cell(int x, int y ) { - if ( x > nx or x < 0 ) { - std::cout << "CaloGrid::cell() Error: out of grid (x)" << std::endl ; - return nullptr; - } - - if ( y > ny or y < 0 ) { - std::cout << "CaloGrid::cell() Error: out of grid (y)" << std::endl ; - return nullptr; - } - - return cells[ x*nx + y ] ; -} - diff --git a/ex4.2/CaloCell.hh b/ex4.2/CaloCell.hh index 30a396d..b26c3c4 100644 --- a/ex4.2/CaloCell.hh +++ b/ex4.2/CaloCell.hh @@ -13,10 +13,10 @@ class CaloCell // No need for Constructor or Destructor double getEnergy() const { return energy; } - bool setEnergy( double new_energy ) { return (energy = new_energy) ; } + void setEnergy( double new_energy ) { energy = new_energy ; } int getId() const { return ID ; } - bool setId( int new_id ) { return ( ID = new_id ) ; } + void setId( int new_id ) { ID = new_id ; } private: diff --git a/ex4.2/CaloGrid.cc b/ex4.2/CaloGrid.cc index 3c52230..cd557f0 100644 --- a/ex4.2/CaloGrid.cc +++ b/ex4.2/CaloGrid.cc @@ -2,17 +2,17 @@ #include #include "CaloGrid.hh" -CaloCell* CaloGrid::cell(int x, int y ) { - if ( x > nx or x < 0 ) { +CaloCell* CaloGrid::cell( int x, int y ) { + if ( x >= nx or x < 0 ) { std::cout << "CaloGrid::cell() Error: out of grid (x)" << std::endl ; return nullptr; } - if ( y > ny or y < 0 ) { + if ( y >= ny or y < 0 ) { std::cout << "CaloGrid::cell() Error: out of grid (y)" << std::endl ; return nullptr; } - return cells[ x * nx + y ] ; + return &cells[ x*nx + y ] ; } diff --git a/ex4.2/CaloGrid.hh b/ex4.2/CaloGrid.hh index ed1da6b..decad8b 100644 --- a/ex4.2/CaloGrid.hh +++ b/ex4.2/CaloGrid.hh @@ -25,6 +25,9 @@ class CaloGrid } CaloCell* cell(int x, int y); + const CaloCell* cell(int x, int y) const { + return const_cast(this)->cell(x, y); + } private: @@ -37,6 +40,13 @@ class CaloGrid // contigious cells cells = new CaloCell[ nx*ny ]; + + // set Cell Ids + for ( int i = 0; i < nx ; i++ ) { + for ( int j = 0; j < ny ; j++ ) { + cells[ i*ny+j ].setId( i*ny+j ); + } + } } } ; #endif diff --git a/ex4.2/Calorimeter.hh b/ex4.2/Calorimeter.hh index e2d79bd..15bba96 100644 --- a/ex4.2/Calorimeter.hh +++ b/ex4.2/Calorimeter.hh @@ -5,5 +5,34 @@ class Calorimeter { -} + public: + Calorimeter( int nx, int ny, double x = 0, double y = 0, double z = 0) : + calogrid(nx, ny), + point(x, y, z) + {} + + Calorimeter( const Calorimeter& other ) : + calogrid( other.calogrid ), + point( other.point ) + {} + + CaloGrid& grid() { + return calogrid; + } + const CaloGrid& grid() const { + return calogrid; + } + + Point& position() { + return point; + } + const Point& position() const { + return point; + } + + private: + Point point; + CaloGrid calogrid; + +}; #endif diff --git a/ex4.2/Point.hh b/ex4.2/Point.hh index 6463376..421de86 100644 --- a/ex4.2/Point.hh +++ b/ex4.2/Point.hh @@ -6,28 +6,29 @@ class Point { public: - Point() { init(0, 0, 0) ; } - Point( double x, double y, double z ) { init( x, y, z ); } + Point( double x = 0, double y = 0, double z = 0) { init( x, y, z ) ; } + + // No need for Constructor or Destructor int getX() const { return x ; } - bool setX( int new_x ) { return ( x = new_x ) ; } + void setX( double new_x ) { x = new_x ; } int getY() const { return y ; } - bool setY( int new_y ) { return ( y = new_y ) ; } + void setY( double new_y ) { y = new_y ; } int getZ() const { return z ; } - bool setZ( int new_z ) { return ( z = new_z ) ; } + void setZ( double new_z ) { z = new_z ; } - void setPoint( double in_x, double in_y, double in_z ) { - x = in_x ; - y = in_y ; - z = in_z ; + void setPoint( double x, double y, double z ) { + setX(x) ; + setY(y) ; + setZ(z) ; } private: void init( double x, double y, double z ) { - setPoint( x, y, z ); + setPoint( x, y, z ) ; } double x, y, z = 0 ; diff --git a/ex4.2/main.cpp b/ex4.2/main.cpp index e617311..56cdd3a 100644 --- a/ex4.2/main.cpp +++ b/ex4.2/main.cpp @@ -1,6 +1,12 @@ +#include "iostream" #include "CaloCell.hh" #include "CaloGrid.hh" #include "Point.hh" +#include "Calorimeter.hh" + +void printCellId( const CaloCell* cell ) { + std::cout << cell->getId() << std::endl; +} int main() { CaloCell cell(0, 1) ; @@ -10,4 +16,19 @@ int main() { grid.cell(1, 1); + + int nx = 3; + int ny = 4; + + Calorimeter calo(nx, ny) ; + + std::cout << "CellId at Start: " << calo.grid().cell(0,0)->getId() << std::endl; + std::cout << "CellId at End: " << calo.grid().cell(nx-1,ny-1)->getId() << std::endl; + + std::cout << "CellId at Center: " ; + printCellId(calo.grid().cell(nx/2,ny/2)); + + + const CaloGrid grid2(5,5); + grid2.cell(3,3); } diff --git a/ex4.3/String.cc b/ex4.3/String.cc index 32b4e50..9566bf2 100644 --- a/ex4.3/String.cc +++ b/ex4.3/String.cc @@ -1,6 +1,7 @@ //String.cc #include "String.hh" +#include String operator+( const String& lhs, const String& rhs ) { String result(lhs); // Copy lhs into res with constructor result += rhs ; // Use operator+= function which is a member of the class @@ -28,3 +29,65 @@ String& String::operator+=( const String& a ) { return *this ; } +String& String::subString( int start, int stop ) { + /* + * Return a substring + * + * if stop is negative, interpret as len - stop + * if start is negative, set start = 0 + * + * if start > stop, return reversed string + */ + + bool reverse = 0; + int len = 0; + char * tmp; + + // Higher than Range + if ( start > _len ) { + start = _len ; + } + + if ( stop > _len ) { + stop = _len ; + } + + // Lower than Range + if ( start < 0 ) { + start = _len + start%_len ; + } + if ( stop < 0 ) { + stop = _len + stop%_len ; + } + + // Set length + len = stop - start; + + if ( start > stop ) { + // Make sure len is positive + len = -1 * len ; + reverse = 1; + } + + // allocate + tmp = new char[ len - 1]; + tmp[len] = '\0'; + + for ( int i = 0 ; i < len ; i++ ) + { + if ( reverse ) + { + tmp[i] = _s[ start - i ]; + } + else + { + tmp[i] = _s[ start + i ]; + } + } + + // make it a String again + String * result = new String(tmp); + delete tmp; + + return *result; +} diff --git a/ex4.3/String.hh b/ex4.3/String.hh index cb2cd91..3bf5eed 100644 --- a/ex4.3/String.hh +++ b/ex4.3/String.hh @@ -12,6 +12,8 @@ public: String& operator=( const String& a ); String& operator+=( const String& a ); + String& subString( int start, int stop ); + operator const char* const() { return data(); } int length() const { return _len ; } @@ -32,4 +34,6 @@ private: } ; +String operator+( const String& lhs, const String& rhs ); + #endif diff --git a/ex4.3/main.cpp b/ex4.3/main.cpp index d4a4e2a..ca61fbe 100644 --- a/ex4.3/main.cpp +++ b/ex4.3/main.cpp @@ -1,6 +1,7 @@ +#include "String.hh" + #include #include -#include "String.hh" int main() { String str("Blubaloo"); @@ -32,4 +33,10 @@ int main() { String c("Almost Empty"); std::cout << "String '" << c.data() << "' is " << strlen(c) << " chars long." << std::endl; + + + // Substring + std::cout << "First five characters: " << c.subString(0, 5) << std::endl; + std::cout << "First five characters reversed: " << c.subString(5, 0) << std::endl; + std::cout << "Last five characters: " << c.subString(-5, -1) << std::endl; } diff --git a/ex5.3/main.cpp b/ex5.3/main.cpp index 1d8ea50..15eb2c8 100644 --- a/ex5.3/main.cpp +++ b/ex5.3/main.cpp @@ -24,9 +24,6 @@ int main( int argc, char* argv[] ) { const int bufsize = 100; char buf[bufsize]; - const int linebufsize = 10; - char linebuf[linebufsize]; - // if EOF, fh returns false while( fh ) { fh.getline(buf, bufsize); @@ -36,8 +33,14 @@ int main( int argc, char* argv[] ) { std::istringstream line(buf); while( line ) { + std::string linebuf; + line >> linebuf; - wordcount++ ; + + if ( ! linebuf.empty() ) { + wordcount++ ; + } + if ( line.eof() ) { @@ -48,5 +51,5 @@ int main( int argc, char* argv[] ) { } - std::cout << " " << linecount-1 << " " << wordcount-1 << " " << charcount-1 << " " << argv[1] << std::endl; + std::cout << " " << linecount-1 << " " << wordcount << " " << charcount-1 << " " << argv[1] << std::endl; } diff --git a/ex6.2/Array.hh b/ex6.2/Array.hh index 84bab41..d1a5eec 100644 --- a/ex6.2/Array.hh +++ b/ex6.2/Array.hh @@ -11,6 +11,7 @@ public: Array(const Array& other) : _size(other._size) { _arr = new T[other._size] ; + _default = other._default; // Copy elements for (int i=0 ; i<_size ; i++) { diff --git a/ex6.3/Array.hh b/ex6.3/Array.hh index 84bab41..96e4f79 100644 --- a/ex6.3/Array.hh +++ b/ex6.3/Array.hh @@ -11,6 +11,7 @@ public: Array(const Array& other) : _size(other._size) { _arr = new T[other._size] ; + _default = other._default ; // Copy elements for (int i=0 ; i<_size ; i++) { diff --git a/ex6.3/Stack.hh b/ex6.3/Stack.hh index 4e68fbc..7487532 100644 --- a/ex6.3/Stack.hh +++ b/ex6.3/Stack.hh @@ -8,23 +8,23 @@ template class Stack { // Interface public: - Stack( int in_size ) { - count = 0; - _s = new Array(in_size, 0); - } + Stack( int size ): + _s(size, 0) + {} int nitems() { return count ; } - bool full() { return (count == _s->size()) ; } + bool full() { return (count == _s.size()) ; } bool empty() { return (count == 0) ; } void push(T c) { if (full()) { std::cout << "Stack::push() Error: stack is full" << std::endl ; - _s->resize( _s->size() + 10 ); + _s.resize( _s.size() + 10 ); + } - _s[0][count++] = c ; + _s[count++] = c ; } T pop() { @@ -33,20 +33,20 @@ class Stack { return 0 ; } - return _s[0][--count] ; + return _s[--count] ; } void inspect() { for ( int i = nitems() - 1; i >= 0; i-- ) { - std::cout << i << ": " << _s[0][i] << std::endl; + std::cout << i << ": " << _s[i] << std::endl; } } // Implementation private: - Array* _s ; - int count ; + Array _s ; + int count = 0; }; #endif diff --git a/ex7.3/conclusion.txt b/ex7.3/conclusion.txt new file mode 100644 index 0000000..51f06d2 --- /dev/null +++ b/ex7.3/conclusion.txt @@ -0,0 +1,3 @@ +The timing is much longer for vectors than for a list. + +However, I also get a segfault for the vector program. diff --git a/ex7.3/list.time b/ex7.3/list.time new file mode 100644 index 0000000..0a6328c --- /dev/null +++ b/ex7.3/list.time @@ -0,0 +1,4 @@ + +real 0m0.028s +user 0m0.021s +sys 0m0.004s diff --git a/ex7.3/main_list.cpp b/ex7.3/main_list.cpp index 0840ee8..436100e 100644 --- a/ex7.3/main_list.cpp +++ b/ex7.3/main_list.cpp @@ -4,7 +4,7 @@ int main() { std::list l; // Fill List - for (int i = 0; i < 10000000 ; i++) { + for (int i = 0; i < 10000 ; i++) { l.push_back(i); } diff --git a/ex7.3/main_vector.cpp b/ex7.3/main_vector.cpp index b790ca3..d1fb8cd 100644 --- a/ex7.3/main_vector.cpp +++ b/ex7.3/main_vector.cpp @@ -13,5 +13,4 @@ int main() { iter = l.erase( iter ); } } - } diff --git a/ex7.3/vector.time b/ex7.3/vector.time new file mode 100644 index 0000000..d1c7d67 --- /dev/null +++ b/ex7.3/vector.time @@ -0,0 +1,5 @@ +Segmentation fault (core dumped) + +real 0m0.927s +user 0m0.349s +sys 0m0.007s diff --git a/ex7.4/Stack.hh b/ex7.4/Stack.hh index e4f3fa1..07ceaa4 100644 --- a/ex7.4/Stack.hh +++ b/ex7.4/Stack.hh @@ -8,18 +8,11 @@ template class Stack { // Interface public: - Stack() { - _s = new std::deque(); - } - ~Stack() { - delete _s; - } - - int nitems() { return _s->size() ; } - bool empty() { return (_s->size() == 0) ; } + int nitems() { return _s.size() ; } + bool empty() { return (_s.size() == 0) ; } void push(T c) { - _s->push_back(c); + _s.push_back(c); } T pop() { @@ -28,15 +21,15 @@ class Stack { return 0 ; } - T tmp = _s->back(); - _s->pop_back(); + T tmp = _s.back(); + _s.pop_back(); return tmp; } void inspect() { - for ( auto iter = _s->begin(); iter != _s->end() ; iter++ ) + for ( auto iter = _s.begin(); iter != _s.end() ; iter++ ) { std::cout << *iter << std::endl; } @@ -44,7 +37,7 @@ class Stack { // Implementation private: - std::deque* _s ; + std::deque _s ; }; #endif diff --git a/ex8.1/Manager.hh b/ex8.1/Manager.hh index 6a099dc..c577561 100644 --- a/ex8.1/Manager.hh +++ b/ex8.1/Manager.hh @@ -36,7 +36,7 @@ public: private: string _name ; double _salary ; - set _subordinates ;// subordinates is an unordered collection so set is usefull enough + set _subordinates ;// subordinates is an unordered collection of unique people so set is usefull enough } ; diff --git a/ex8.2/Manager.hh b/ex8.2/Manager.hh index 6a099dc..c577561 100644 --- a/ex8.2/Manager.hh +++ b/ex8.2/Manager.hh @@ -36,7 +36,7 @@ public: private: string _name ; double _salary ; - set _subordinates ;// subordinates is an unordered collection so set is usefull enough + set _subordinates ;// subordinates is an unordered collection of unique people so set is usefull enough } ; diff --git a/ex8.2/main.cpp b/ex8.2/main.cpp index 5f32235..96efd77 100644 --- a/ex8.2/main.cpp +++ b/ex8.2/main.cpp @@ -10,15 +10,15 @@ void populate_directory( set& directory ) { Manager* jo = new Manager("Jo", 5); Manager* frank = new Manager("Frank", 6); - (*stan).addSubordinate( *wouter ); - (*stan).addSubordinate( *ivo ); + stan->addSubordinate( *wouter ); + stan->addSubordinate( *ivo ); directory.insert( stan ); directory.insert( wouter ); // This does not give a problem because stan is also of type Employee - (*frank).addSubordinate( *stan ); - (*frank).addSubordinate( *jo ); + frank->addSubordinate( *stan ); + frank->addSubordinate( *jo ); directory.insert( wouter ); directory.insert( ivo ); diff --git a/ex8.3/Circle.hh b/ex8.3/Circle.hh index 00a50b9..bcceb88 100644 --- a/ex8.3/Circle.hh +++ b/ex8.3/Circle.hh @@ -9,7 +9,7 @@ class Circle: public Shape { public: // Constructor, destructor - Circle(int radius) : _radius(radius) {} ; + Circle( double radius ) : _radius(radius) {} ; virtual ~Circle() {} ; // Implementation of abstract interface @@ -18,6 +18,6 @@ public: virtual const char* shapeName() const { return "Circle"; } private: - int _radius ; + double _radius ; } ; #endif diff --git a/ex9.1/d.cpp b/ex9.1/d.cpp new file mode 100644 index 0000000..5b2d92d --- /dev/null +++ b/ex9.1/d.cpp @@ -0,0 +1,82 @@ +#include +#include +#include +#include +#include +#include + +/* + * Compile with 'g++ -pthread a.cpp' + * + * Modifying an object + */ + +using namespace std; + +/* + * This method will push the addition of the last two elements on the vector. + */ +void manipulate(vector& v) { + int sleep = 2; + for ( int i = 0; i < 5; i++ ) + { + double a = 0; + + // Only use the last two elements + int j = 0; + for ( auto rit = v.rbegin() ; rit != v.rend(); ++rit ) + { + if ( j > 1 ) + { + break; + } + + a += *rit; + ++j; + } + + v.push_back( a); + std::cout << "Updated Vector" << std::endl; + + this_thread::sleep_for(std::chrono::seconds(sleep)); + } +} + +void display(vector& v) { + int sleep = 1; + for ( int i = 0; i < 10; i++ ) + { + std::cout << "Vector is now:" << std::endl; + + std::cout << "{"; + for ( int i = 0; i < v.size() ; i++ ) { + std::cout << v[i] << ", "; + } + std::cout << "}" << std::endl; + this_thread::sleep_for(std::chrono::seconds(sleep)); + } +} + + +struct my_f { + vector& v; + + my_f(vector& vv): v(vv) {}; + void my_function() { manipulate(v); }; +}; + +int main() { + + vector v { 1.1, 1.1 }; + thread t {display, ref(v)}; + + my_f f{v}; + thread t2( &my_f::my_function, std::ref(f) ); + + + // Run the threads + t.join(); + t2.join(); + + return 0; +} diff --git a/pdfs/Advanced-Programming.pdf b/pdfs/Advanced-Programming.pdf new file mode 100644 index 0000000..ca541df Binary files /dev/null and b/pdfs/Advanced-Programming.pdf differ diff --git a/pdfs/Chapter1-reduced.pdf b/pdfs/Chapter1-reduced.pdf new file mode 100644 index 0000000..d07e839 Binary files /dev/null and b/pdfs/Chapter1-reduced.pdf differ diff --git a/pdfs/Chapter2.pdf b/pdfs/Chapter2.pdf new file mode 100644 index 0000000..a970a6a Binary files /dev/null and b/pdfs/Chapter2.pdf differ diff --git a/pdfs/Chapter3.pdf b/pdfs/Chapter3.pdf new file mode 100644 index 0000000..d23ad59 Binary files /dev/null and b/pdfs/Chapter3.pdf differ diff --git a/pdfs/Chapter4.pdf b/pdfs/Chapter4.pdf new file mode 100644 index 0000000..2997456 Binary files /dev/null and b/pdfs/Chapter4.pdf differ diff --git a/pdfs/Chapter5.pdf b/pdfs/Chapter5.pdf new file mode 100644 index 0000000..d72b436 Binary files /dev/null and b/pdfs/Chapter5.pdf differ diff --git a/pdfs/Chapter6.pdf b/pdfs/Chapter6.pdf new file mode 100644 index 0000000..06d6ec5 Binary files /dev/null and b/pdfs/Chapter6.pdf differ diff --git a/pdfs/Chapter7.pdf b/pdfs/Chapter7.pdf new file mode 100644 index 0000000..fe05e40 Binary files /dev/null and b/pdfs/Chapter7.pdf differ diff --git a/pdfs/Chapter8.pdf b/pdfs/Chapter8.pdf new file mode 100644 index 0000000..8d52846 Binary files /dev/null and b/pdfs/Chapter8.pdf differ diff --git a/pdfs/Chapter9-concurrency.pdf b/pdfs/Chapter9-concurrency.pdf new file mode 100644 index 0000000..07c5f5c Binary files /dev/null and b/pdfs/Chapter9-concurrency.pdf differ diff --git a/pdfs/Introduction.pdf b/pdfs/Introduction.pdf new file mode 100644 index 0000000..7c60b6c Binary files /dev/null and b/pdfs/Introduction.pdf differ diff --git a/pdfs/Table of Contents.html b/pdfs/Table of Contents.html new file mode 100644 index 0000000..b3c5cfa --- /dev/null +++ b/pdfs/Table of Contents.html @@ -0,0 +1 @@ +1920 CDS: Advanced Programming (KW2 V)
 
1920 CDS: Advanced Programming (KW2 V)

1. Advanced-Programming

2. exercises

3. Introduction

4. Course material

5. exercises

6. Course material

7. exercises

8. Course material

9. exercises

10. Course material

11. exercises

12. Course material

13. exercises

14. Course material

15. exercises

16. Course material

17. exercises

18. Course material

19. exercises

20. Chapter9-concurrency

21. exercises

22. chapter10-bindings

23. exercise

\ No newline at end of file diff --git a/pdfs/chapter10-bindings.pdf b/pdfs/chapter10-bindings.pdf new file mode 100644 index 0000000..869ee5c Binary files /dev/null and b/pdfs/chapter10-bindings.pdf differ diff --git a/pdfs/exercise10.pdf b/pdfs/exercise10.pdf new file mode 100644 index 0000000..9c83cd7 Binary files /dev/null and b/pdfs/exercise10.pdf differ diff --git a/pdfs/exercises0.pdf b/pdfs/exercises0.pdf new file mode 100644 index 0000000..330b471 Binary files /dev/null and b/pdfs/exercises0.pdf differ diff --git a/pdfs/exercises1-reduced.pdf b/pdfs/exercises1-reduced.pdf new file mode 100644 index 0000000..4e90aa0 Binary files /dev/null and b/pdfs/exercises1-reduced.pdf differ diff --git a/pdfs/exercises2.pdf b/pdfs/exercises2.pdf new file mode 100644 index 0000000..7e541e5 Binary files /dev/null and b/pdfs/exercises2.pdf differ diff --git a/pdfs/exercises3.pdf b/pdfs/exercises3.pdf new file mode 100644 index 0000000..8dcc997 Binary files /dev/null and b/pdfs/exercises3.pdf differ diff --git a/pdfs/exercises4.pdf b/pdfs/exercises4.pdf new file mode 100644 index 0000000..4607cea Binary files /dev/null and b/pdfs/exercises4.pdf differ diff --git a/pdfs/exercises5.pdf b/pdfs/exercises5.pdf new file mode 100644 index 0000000..e9d86a6 Binary files /dev/null and b/pdfs/exercises5.pdf differ diff --git a/pdfs/exercises6.pdf b/pdfs/exercises6.pdf new file mode 100644 index 0000000..88fa9cb Binary files /dev/null and b/pdfs/exercises6.pdf differ diff --git a/pdfs/exercises7.pdf b/pdfs/exercises7.pdf new file mode 100644 index 0000000..cd962ed Binary files /dev/null and b/pdfs/exercises7.pdf differ diff --git a/pdfs/exercises8.pdf b/pdfs/exercises8.pdf new file mode 100644 index 0000000..d6628fb Binary files /dev/null and b/pdfs/exercises8.pdf differ diff --git a/pdfs/exercises91.pdf b/pdfs/exercises91.pdf new file mode 100644 index 0000000..c43a874 Binary files /dev/null and b/pdfs/exercises91.pdf differ