From 403716e64f5a8732bdaeca43838195e8db3b0ac3 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Fri, 20 May 2022 17:58:16 +0200 Subject: Added shape.cpp for comparison. Renamed some examples. --- examples/ex_gauss1.c | 58 ------------------------ examples/ex_gauss2.c | 41 ----------------- examples/gauss1.c | 58 ++++++++++++++++++++++++ examples/gauss2.c | 41 +++++++++++++++++ examples/shape.c | 84 +++++++++++++++++------------------ examples/shape.cpp | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 262 insertions(+), 142 deletions(-) delete mode 100644 examples/ex_gauss1.c delete mode 100644 examples/ex_gauss2.c create mode 100644 examples/gauss1.c create mode 100644 examples/gauss2.c create mode 100644 examples/shape.cpp diff --git a/examples/ex_gauss1.c b/examples/ex_gauss1.c deleted file mode 100644 index 081a4a73..00000000 --- a/examples/ex_gauss1.c +++ /dev/null @@ -1,58 +0,0 @@ -#include -#include -#include -#include -#include - -// Declare int -> int hashmap. Uses typetag 'ii' for ints. -#define i_key int32_t -#define i_val size_t -#define i_tag ii -#include - -// Declare int vector with map entries that can be sorted by map keys. -struct { int first; size_t second; } typedef mapval; - -#define i_val mapval -#define i_less(x, y) x->first < y->first -#define i_tag pair -#include - -int main() -{ - enum {N = 10000000}; - const double Mean = -12.0, StdDev = 6.0, Scale = 74; - - printf("Demo of gaussian / normal distribution of %d random samples\n", N); - - // Setup random engine with normal distribution. - uint64_t seed = time(NULL); - stc64_t rng = stc64_new(seed); - stc64_normalf_t dist = stc64_normalf_new(Mean, StdDev); - - // Create and init histogram vec and map with defered destructors: - c_auto (cvec_pair, histvec) - c_auto (cmap_ii, histmap) - { - c_forrange (N) { - int index = (int) round( stc64_normalf(&rng, &dist) ); - cmap_ii_insert(&histmap, index, 0).ref->second += 1; - } - - // Transfer map to vec and sort it by map keys. - c_foreach (i, cmap_ii, histmap) - cvec_pair_push_back(&histvec, (mapval){i.ref->first, i.ref->second}); - - cvec_pair_sort(&histvec); - - // Print the gaussian bar chart - c_auto (cstr, bar) - c_foreach (i, cvec_pair, histvec) { - size_t n = (size_t) (i.ref->second * StdDev * Scale * 2.5 / (float)N); - if (n > 0) { - cstr_resize(&bar, n, '*'); - printf("%4d %s\n", i.ref->first, cstr_str(&bar)); - } - } - } -} diff --git a/examples/ex_gauss2.c b/examples/ex_gauss2.c deleted file mode 100644 index 9558afd3..00000000 --- a/examples/ex_gauss2.c +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include -#include -#include - -// Declare int -> int sorted map. -#define i_key int -#define i_val size_t -#include - -int main() -{ - enum {N = 10000000}; - const double Mean = -12.0, StdDev = 6.0, Scale = 74; - - printf("Demo of gaussian / normal distribution of %d random samples\n", N); - - // Setup random engine with normal distribution. - uint64_t seed = time(NULL); - stc64_t rng = stc64_new(seed); - stc64_normalf_t dist = stc64_normalf_new(Mean, StdDev); - - // Create and init histogram map with defered destruct - c_auto (csmap_int, mhist) - { - c_forrange (N) { - int index = (int) round( stc64_normalf(&rng, &dist) ); - csmap_int_insert(&mhist, index, 0).ref->second += 1; - } - - // Print the gaussian bar chart - c_auto (cstr, bar) - c_forpair (index, count, csmap_int, mhist) { - size_t n = (size_t) (_.count * StdDev * Scale * 2.5 / (float)N); - if (n > 0) { - cstr_resize(&bar, n, '*'); - printf("%4d %s\n", _.index, cstr_str(&bar)); - } - } - } -} diff --git a/examples/gauss1.c b/examples/gauss1.c new file mode 100644 index 00000000..081a4a73 --- /dev/null +++ b/examples/gauss1.c @@ -0,0 +1,58 @@ +#include +#include +#include +#include +#include + +// Declare int -> int hashmap. Uses typetag 'ii' for ints. +#define i_key int32_t +#define i_val size_t +#define i_tag ii +#include + +// Declare int vector with map entries that can be sorted by map keys. +struct { int first; size_t second; } typedef mapval; + +#define i_val mapval +#define i_less(x, y) x->first < y->first +#define i_tag pair +#include + +int main() +{ + enum {N = 10000000}; + const double Mean = -12.0, StdDev = 6.0, Scale = 74; + + printf("Demo of gaussian / normal distribution of %d random samples\n", N); + + // Setup random engine with normal distribution. + uint64_t seed = time(NULL); + stc64_t rng = stc64_new(seed); + stc64_normalf_t dist = stc64_normalf_new(Mean, StdDev); + + // Create and init histogram vec and map with defered destructors: + c_auto (cvec_pair, histvec) + c_auto (cmap_ii, histmap) + { + c_forrange (N) { + int index = (int) round( stc64_normalf(&rng, &dist) ); + cmap_ii_insert(&histmap, index, 0).ref->second += 1; + } + + // Transfer map to vec and sort it by map keys. + c_foreach (i, cmap_ii, histmap) + cvec_pair_push_back(&histvec, (mapval){i.ref->first, i.ref->second}); + + cvec_pair_sort(&histvec); + + // Print the gaussian bar chart + c_auto (cstr, bar) + c_foreach (i, cvec_pair, histvec) { + size_t n = (size_t) (i.ref->second * StdDev * Scale * 2.5 / (float)N); + if (n > 0) { + cstr_resize(&bar, n, '*'); + printf("%4d %s\n", i.ref->first, cstr_str(&bar)); + } + } + } +} diff --git a/examples/gauss2.c b/examples/gauss2.c new file mode 100644 index 00000000..9558afd3 --- /dev/null +++ b/examples/gauss2.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include + +// Declare int -> int sorted map. +#define i_key int +#define i_val size_t +#include + +int main() +{ + enum {N = 10000000}; + const double Mean = -12.0, StdDev = 6.0, Scale = 74; + + printf("Demo of gaussian / normal distribution of %d random samples\n", N); + + // Setup random engine with normal distribution. + uint64_t seed = time(NULL); + stc64_t rng = stc64_new(seed); + stc64_normalf_t dist = stc64_normalf_new(Mean, StdDev); + + // Create and init histogram map with defered destruct + c_auto (csmap_int, mhist) + { + c_forrange (N) { + int index = (int) round( stc64_normalf(&rng, &dist) ); + csmap_int_insert(&mhist, index, 0).ref->second += 1; + } + + // Print the gaussian bar chart + c_auto (cstr, bar) + c_forpair (index, count, csmap_int, mhist) { + size_t n = (size_t) (_.count * StdDev * Scale * 2.5 / (float)N); + if (n > 0) { + cstr_resize(&bar, n, '*'); + printf("%4d %s\n", _.index, cstr_str(&bar)); + } + } + } +} diff --git a/examples/shape.c b/examples/shape.c index a922cdf1..816fdea4 100644 --- a/examples/shape.c +++ b/examples/shape.c @@ -13,23 +13,26 @@ c_static_assert(offsetof(T, base) == 0); \ static Api T##_api - // Shape definition // ============================================================ -typedef struct { float x, y; } Point; +typedef struct { + float x, y; +} Point; -typedef struct { +typedef struct Shape Shape; + +struct ShapeAPI { + void (*drop)(Shape*); + void (*draw)(const Shape*); +}; + +struct Shape { struct ShapeAPI* api; uint32_t color; uint16_t style; uint8_t thickness; uint8_t hardness; -} Shape; - -struct ShapeAPI { - void (*drop)(Shape*); - void (*draw)(const Shape*); }; void Shape_drop(Shape* shape) @@ -43,7 +46,6 @@ void Shape_delete(Shape* shape) shape->api->drop(shape); c_free(shape); } - printf("shape deleted\n"); } // Triangle implementation @@ -57,6 +59,11 @@ typedef struct { c_vtable(struct ShapeAPI, Triangle); +Triangle* Triangle_new(Point a, Point b, Point c) +{ + return c_new(Triangle, {{.api=&Triangle_api}, .p={a, b, c}}); +} + static void Triangle_draw(const Shape* shape) { const c_self(shape, Triangle); @@ -71,31 +78,36 @@ static struct ShapeAPI Triangle_api = { .draw = Triangle_draw, }; -Triangle* Triangle_new(Point a, Point b, Point c) -{ - return c_new(Triangle, {{.api=&Triangle_api}, .p={a, b, c}}); -} - // Polygon implementation // ============================================================ -#define i_type PntVec +#define i_type PointVec #define i_val Point #include typedef struct { Shape base; - PntVec points; + PointVec points; } Polygon; c_vtable(struct ShapeAPI, Polygon); +Polygon* Polygon_new(void) +{ + return c_new(Polygon, {{.api=&Polygon_api}, .points=PointVec_init()}); +} + +void Polygon_addPoint(Polygon* self, Point p) +{ + PointVec_push(&self->points, p); +} + static void Polygon_drop(Shape* shape) { c_self(shape, Polygon); printf("poly destructed\n"); - PntVec_drop(&self->points); + PointVec_drop(&self->points); Shape_drop(shape); } @@ -103,7 +115,7 @@ static void Polygon_draw(const Shape* shape) { const c_self(shape, Polygon); printf("Polygon :"); - c_foreach (i, PntVec, self->points) + c_foreach (i, PointVec, self->points) printf(" (%g,%g)", i.ref->x, i.ref->y); puts(""); } @@ -113,27 +125,15 @@ static struct ShapeAPI Polygon_api = { .draw = Polygon_draw, }; -Polygon* Polygon_new(void) -{ - return c_new(Polygon, {{.api=&Polygon_api}, .points=PntVec_init()}); -} - -void Polygon_addPoint(Polygon* self, Point p) -{ - PntVec_push(&self->points, p); -} - - // Test // ============================================================ #define i_type Shapes #define i_val Shape* -#define i_opt c_no_clone #define i_valdrop(x) Shape_delete(*x) #include -void testShape(Shape* shape) +void testShape(const Shape* shape) { shape->api->draw(shape); } @@ -143,21 +143,19 @@ int main(void) { c_auto (Shapes, shapes) { - Triangle* t1 = Triangle_new((Point){5, 7}, (Point){12, 7}, (Point){12, 20}); + Triangle* tri1 = Triangle_new((Point){5, 7}, (Point){12, 7}, (Point){12, 20}); + Polygon* pol1 = Polygon_new(); + Polygon* pol2 = Polygon_new(); - Polygon* p1 = Polygon_new(); - c_apply(pnt, Polygon_addPoint(p1, pnt), Point, { - {50, 72}, {123, 73}, {127, 201}, {828, 333}, - }); + c_apply(p, Polygon_addPoint(pol1, p), Point, + {{50, 72}, {123, 73}, {127, 201}, {828, 333}}); - Polygon* p2 = Polygon_new(); - c_apply(pnt, Polygon_addPoint(p2, pnt), Point, { - {5, 7}, {12, 7}, {12, 20}, {82, 33}, {17, 56}, - }); + c_apply(p, Polygon_addPoint(pol2, p), Point, + {{5, 7}, {12, 7}, {12, 20}, {82, 33}, {17, 56}}); - Shapes_push(&shapes, &t1->base); - Shapes_push(&shapes, &p1->base); - Shapes_push(&shapes, &p2->base); + Shapes_push(&shapes, &tri1->base); + Shapes_push(&shapes, &pol1->base); + Shapes_push(&shapes, &pol2->base); c_foreach (i, Shapes, shapes) testShape(*i.ref); diff --git a/examples/shape.cpp b/examples/shape.cpp new file mode 100644 index 00000000..b451b5ba --- /dev/null +++ b/examples/shape.cpp @@ -0,0 +1,122 @@ +// Demo of polymorphism in C++ + +#include +#include +#include + +// Shape definition +// ============================================================ + +struct Point { + float x, y; +}; + +std::ostream& operator<<(std::ostream& os, const Point& p) { + os << " (" << p.x << "," << p.y << ")"; + return os; +} + +struct Shape { + virtual ~Shape(); + virtual void draw() const = 0; + + uint32_t color; + uint16_t style; + uint8_t thickness; + uint8_t hardness; +}; + +Shape::~Shape() +{ + std::cout << "base destructed" << std::endl; +} + +// Triangle implementation +// ============================================================ + +struct Triangle : public Shape +{ + Triangle(Point a, Point b, Point c); + void draw() const override; + + private: Point p[3]; +}; + + +Triangle::Triangle(Point a, Point b, Point c) + : p{a, b, c} {} + +void Triangle::draw() const +{ + std::cout << "Triangle :" + << p[0] << p[1] << p[2] + << std::endl; +} + + +// Polygon implementation +// ============================================================ + + +struct Polygon : public Shape +{ + ~Polygon(); + void draw() const override; + void addPoint(const Point& p); + + private: std::vector points; +}; + + +void Polygon::addPoint(const Point& p) +{ + points.push_back(p); +} + +Polygon::~Polygon() +{ + std::cout << "poly destructed" << std::endl; +} + +void Polygon::draw() const +{ + std::cout << "Polygon :"; + for (auto& p : points) + std::cout << p ; + std::cout << std::endl; +} + + +// Test +// ============================================================ + +void testShape(const Shape* shape) +{ + shape->draw(); +} + +#include + +int main(void) +{ + std::vector> shapes; + + auto tri1 = std::make_unique(Point{5, 7}, Point{12, 7}, Point{12, 20}); + auto pol1 = std::make_unique(); + auto pol2 = std::make_unique(); + + for (auto& p: std::array + {{{50, 72}, {123, 73}, {127, 201}, {828, 333}}}) + pol1->addPoint(p); + + for (auto& p: std::array + {{{5, 7}, {12, 7}, {12, 20}, {82, 33}, {17, 56}}}) + pol2->addPoint(p); + + shapes.push_back(std::move(tri1)); + shapes.push_back(std::move(pol1)); + shapes.push_back(std::move(pol2)); + + for (auto& shape: shapes) + testShape(shape.get()); +} -- cgit v1.2.3