generic programming library development
play

Generic programming & library development Today: Generic - PowerPoint PPT Presentation

Generic programming & library development Today: Generic programming techniques power of templates design patterns Lecturer: Jyrki Katajainen Some of these slides are from Kenny Erleben Course home page:


  1. Generic programming & library development Today: Generic programming techniques • power of templates • design patterns Lecturer: Jyrki Katajainen Some of these slides are from Kenny Erleben Course home page: http://www.diku.dk/forskning/performance-engineering/ Generic-programming/ c � Performance Engineering Laboratory Generic programming and library development, 29 April 2008 (1)

  2. Polymorphism The word polymorphism means “the ability to have many forms”. Parametric polymorphism: C ++ templates Inclusion polymorphism: C ++ virtual functions Overloading: C ++ function overloading including partial specializa- tion Coercion: C ++ built-in or user defined conversion operators or con- structors to coercion c � Performance Engineering Laboratory Generic programming and library development, 29 April 2008 (2)

  3. Dynamic polymorphism: base class A traditional approach where common behaviour is defined in an ab- stract base class class Shape { public: virtual int id() const = 0; virtual std::string type() const = 0; // ... }; c � Performance Engineering Laboratory Generic programming and library development, 29 April 2008 (3)

  4. Dynamic polymorphism: derived classes class Sphere : public Shape { public: virtual int id() const { return 1; } virtual std::string type() const { return "sphere"; } }; class Box : public Shape { public: virtual int id() const { return 2; } virtual std::string type() const { return "box"; } }; and so on... (Question: Why are all member functions virtual?) c � Performance Engineering Laboratory Generic programming and library development, 29 April 2008 (4)

  5. Dynamic polymorphism: test functions Let us define some functions that operate on different shapes void pair_test(Shape const* A, Shape const* B) { std::cout << "collision�detection:" << (*A).type() << "�and�" << (*B).type() << std::endl; } Or a little more exotic void collision(std::vector<Shape*> const& shapes) { for(unsigned i = 0; i < shapes.size(); ++i) { for(unsigned j = i + 1; j < shapes.size(); ++j) { pair_test(shapes[i], shapes[j]); } } } c � Performance Engineering Laboratory Generic programming and library development, 29 April 2008 (5)

  6. Dynamic polymorphism: usage Let us try our example functions int main() { Sphere s0; Sphere s1; Box b0; Box b1; Box b2; pair_test(&b2, &s1); std::vector<Shape*> shapes; shapes.push_back(&s0); shapes.push_back(&s1); shapes.push_back(&b0); shapes.push_back(&b1); shapes.push_back(&b2); collision(shapes); } c � Performance Engineering Laboratory Generic programming and library development, 29 April 2008 (6)

  7. Dynamic polymorphism: summary • The interface is bounded, • the binding of interfaces is done at run time (dynamically), and • it is easy to create heterogeneous containers. • What if we want to extend with a new shape? class Prism : public Shape... • What if we want to extend with a new function? virtual point centre_of_gravity() const = 0; c � Performance Engineering Laboratory Generic programming and library development, 29 April 2008 (7)

  8. Static polymorphism Let us try to use templates instead of inheritance class Sphere { public: int id() const { return 1; } std::string type() const { return "sphere"; } }; class Box { public: int id() const { return 2; } std::string type() const { return "box"; } }; c � Performance Engineering Laboratory Generic programming and library development, 29 April 2008 (8)

  9. Static polymorphism: testing We also need to rewrite our test functions template <typename Shape1, typename Shape2> void pair_test(Shape1 const& A, Shape2 const& B) { std::cout << "collision�detection:" << A.type() << "�and�" << B.type() << std::endl; } and we can now use it int main() { ... pair_test(b0, s1); ... pair_test(b2, s2); } c � Performance Engineering Laboratory Generic programming and library development, 29 April 2008 (9)

  10. Static polymorphism: falling short What about? void collision(std::vector<Shape*> const& shapes) { for(unsigned i = 0; i < shapes.size(); ++i) { for(unsigned j = i + 1; j < shapes.size(); ++j) { pair_test(shapes[i], shapes[j]); } } } • Sorry, this is impossible; we cannot handle this transparently! std::vector<Shape*> const& shapes c � Performance Engineering Laboratory Generic programming and library development, 29 April 2008 (10)

  11. Static polymorphism: summary • The interface is unbounded, • the binding of interfaces is done at compile time (statically), and • one cannot create heterogeneous containers. • What if we want to extend with a new shape? class Prism • What if we want to extend with a new function? bool centre_of_gravity() const { ... }; c � Performance Engineering Laboratory Generic programming and library development, 29 April 2008 (11)

  12. Design pattern: bridge Decouple an abstraction from its implementation so that the two can vary independently. • Possible to provide several implementations with the same inter- face. • Clients can select the best implementations for their purposes. • Implementations can be smaller than the bridge (that is, pieces identical to all implementations are implemented at the bridge). c � Performance Engineering Laboratory Generic programming and library development, 29 April 2008 (12)

  13. Bridge pattern implemented using inheritance R B virtual operationA() = 0; R* realization; virtual operationB() = 0; operationA(); operationB(); implemention 1 implemention 2 operationC(); operationA(); operationA(); operationB(); operationB(); Source: [Vandevoorde and Josuttis 2003, § 14.4] c � Performance Engineering Laboratory Generic programming and library development, 29 April 2008 (13)

  14. Bridge pattern implemented using templates R B R realization; operationA(); operationB(); implemention 1 implemention 2 operationC(); operationA(); operationA(); operationB(); operationB(); Source: [Vandevoorde and Josuttis 2003, § 14.4] c � Performance Engineering Laboratory Generic programming and library development, 29 April 2008 (14)

  15. Stack bridge versus stack kernel template < template < typename V, typename V, typename A = std::allocator<V>, typename A = std::allocator<V>, typename R = cphstl::list_stack<V, A> typename R = std::list<V, A> > > class stack { class list_stack { public: public: ... ... size_type size() const; typedef std::size_t size_type; bool empty() const; ... protected: size_type size() const; R kernel; ... }; }; template <typename V, typename A, typename R> typename stack<V, A, R>::size_type stack<V, A, R>::size() const { return kernel.size(); } c � Performance Engineering Laboratory Generic programming and library development, 29 April 2008 (15)

  16. Design pattern: iterator Provide a way to access the elements of a container sequentially without exposing its underlying representation. • In the C ++ standard library, iterators come in several different flavours: locators (or trivial iterators), input iterators, output iter- ators, forward iterators, bidirectional iterators, and random-access iterators. • Iterators are generalizations of pointers. c � Performance Engineering Laboratory Generic programming and library development, 29 April 2008 (16)

  17. Iterators as the clue Source: David R. Musser, et al., STL Tutorial and Reference Guide: C ++ Program- ming with the Standard Template Library , 2nd Edition, Addison-Wesley (2001) c � Performance Engineering Laboratory Generic programming and library development, 29 April 2008 (17)

  18. Generic function accumulate Let n be a non-negative integer and x i a value of type V for i ∈ { 0 , 1 , . . . , n − 1 } . Assume that operator+ is defined for V . Function accumulate computes � n − 1 i =0 x i for any sequence of elements of type V . #include <iterator> // defines std::iterator_traits template <typename I> typename std::iterator_traits<I>::value_type accumulate(I p, I q) { typedef typename std::iterator_traits<I>::value_type V; V total = V(); while (p �≡ q) { total += *p; ++p; } return total; } c � Performance Engineering Laboratory Generic programming and library development, 29 April 2008 (18)

  19. Facilities available at compile time 1. Template parameters can be types. 2. Template parameters can be integral values (e.g. of type int , short , char , bool , or an enumeration type). 3. Template parameters can be templates, pointers, or functions. 4. sizeof can be evaluated at compile time. Surprisingly, the template mechanisms available in C ++ can be exploit- ed as a fully-fledged programming language. c � Performance Engineering Laboratory Generic programming and library development, 29 April 2008 (19)

Recommend


More recommend