Interfaces in Cilk

Interfaces are named collections of method signatures.

#include <iostream>
#include <cmath>
#include <memory>

// Here's a basic interface for geometric shapes.
class geometry {
public:
    virtual double area() = 0;
    virtual double perim() = 0;
    virtual ~geometry() {}
};

// For our example we'll implement this interface on
// rect and circle types.
class rect : public geometry {
private:
    double width, height;
public:
    rect(double w, double h) : width(w), height(h) {}
    double area() override {
        return width * height;
    }
    double perim() override {
        return 2*width + 2*height;
    }
};

class circle : public geometry {
private:
    double radius;
public:
    circle(double r) : radius(r) {}
    double area() override {
        return M_PI * radius * radius;
    }
    double perim() override {
        return 2 * M_PI * radius;
    }
};

// If a variable has an interface type, then we can call
// methods that are in the named interface. Here's a
// generic measure function taking advantage of this
// to work on any geometry.
void measure(const std::shared_ptr<geometry>& g) {
    std::cout << g->area() << std::endl;
    std::cout << g->perim() << std::endl;
}

cilk_int main() {
    auto r = std::make_shared<rect>(3, 4);
    auto c = std::make_shared<circle>(5);

    // The circle and rect struct types both
    // implement the geometry interface so we can use
    // instances of these structs as arguments to measure.
    measure(r);
    measure(c);

    return 0;
}

To compile and run this Cilk program:

$ clang++ -fopencilk -O3 interfaces.cpp -o interfaces
$ ./interfaces
12
14
78.5398
31.4159

In this Cilk version, we’ve used C++ classes to implement the interface concept. The geometry class serves as our interface, with pure virtual functions area() and perim(). The rect and circle classes inherit from geometry and implement these methods.

We use std::shared_ptr to manage the lifetime of our objects, which allows us to use polymorphism safely. The measure function takes a std::shared_ptr<geometry>, which can point to either a rect or a circle.

The cilk_int main() function is the entry point for a Cilk program, similar to main() in C++.

Note that Cilk extends C++ with parallel programming constructs, but in this example, we’re not using any parallel features. The program structure remains similar to the original, demonstrating how interfaces work in an object-oriented context.