1 / 24

Concepts: Linguistic Support for Generic Programming in C++

Concepts: Linguistic Support for Generic Programming in C++. Jaakko Järvi Bjarne Stroustrup Andrew Lumsdaine. Douglas Gregor Jeremy Siek Gabriel Dos Reis. Generic Programming. A methodology for the construction of generic software libraries. Dual focus on abstraction and efficiency

joelle
Download Presentation

Concepts: Linguistic Support for Generic Programming in C++

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Concepts: Linguistic Support for Generic Programming in C++ Jaakko Järvi Bjarne Stroustrup Andrew Lumsdaine Douglas Gregor Jeremy Siek Gabriel Dos Reis

  2. Generic Programming • A methodology for the construction of generic software libraries. • Dual focus on abstraction and efficiency • Example: The C++ Standard Template Library • Core notion: Lifting an algorithm • Start with concrete algorithms: int gcd(int a, int b) { ... } • Remove unnecessary requirements:template<typename Integral> Integral gcd(Integral a, Integral b) { ... } • Repeat: lift Integral to CommutativeRing

  3. Generic Programming in C++ • C++ templates enable the application of GP • Overloading permits natural abstractions • Instantiation eliminates cost of abstractions • Many successful, generic libraries in C++ • Significant problems remain: • Inability to directly express ideas of GP • Generic libraries in C++ are fragile Can we design better support for Generic Programming in C++ without sacrificing the performance and flexibility of templates?

  4. Concepts for C++: Goals • Support for the core ideas of Generic Programming in C++ • Modular type checking for C++ templates • Performance equivalent to C++ templates • Complete backward compatibility • Library evolution is particularly important • Simplicity • Implementability

  5. Concepts Overview • Three major parts: • Concept definitions: Specify the behavior of classes of types via requirements. • Where clauses: Specify constraints on template parameters in terms of concepts. • Concept maps: Specify how types meet the requirements of a concept.

  6. Constrained Templates • Place constraints on template parameters via a where clause • Uses of the template must satisfy these constraints • Definition of the template can assume only what the constraints imply template<typename T> where LessThanComparable<T> const T& min(const T& x, const T& y) { return x < y? x : y; }

  7. Concept Definitions • Concept definitions state requirements on type parameters. concept LessThanComparable<typename T> { bool operator<(T, T); axiom Irreflexivity(T x) { !(x < x); } axiom Transitivity(T x, T y, T z) { if (x < y && y < z) x < z; } }

  8. Concept Parameterization • Concepts can have any number of parameters: concept EqualityComparable<typename T, typename U> { bool operator==(T, U); bool operator!=(T, U); }

  9. Iterator Concepts • Iterators abstract the notion of a sequence of values. concept InputIterator<typename Iter> { Iter& operator++(Iter&); // pre-increment Iter operator++(Iter&, int); // post-increment bool operator==(Iter, Iter); // equality comparison bool operator!=(Iter, Iter); // inequality comparison ??? operator*(Iter); // dereference };

  10. Iterators & Associated Types • value_type is the type that the iterator points to concept InputIterator<typename Iter> { typename value_type; Iter& operator++(Iter&); // pre-increment Iter operator++(Iter&, int); // post-increment bool operator==(Iter, Iter); // equality comparison bool operator!=(Iter, Iter); // inequality comparison value_type operator*(Iter); // dereference };

  11. Iterators & Nested Requirements • difference_type measures sequence length concept InputIterator<typename Iter> { typename value_type; typename difference_type; where SignedIntegral<difference_type>; Iter& operator++(Iter&); // pre-increment Iter operator++(Iter&, int); // post-increment bool operator==(Iter, Iter); // equality comparison bool operator!=(Iter, Iter); // inequality comparison value_type operator*(Iter); // dereference };

  12. Using Associated Types • Implementing the STL find with concepts: template<typename Iter, typename T> where InputIterator<Iter> && EqualityComparable<InputIterator<Iter>::value_type, T> Iter find(Iter first, Iter last, const T& value) { while (first != last && !(*first == value)) ++first; return first; }

  13. Concept Maps • We want to call find with an array of integers: bool contains(int* array, int n, int value) { return find(array, array + n, value) != array + n; } • Concept maps satisfy concept constraints: concept_map InputIterator<int*> { typedef int value_type; typedef ptrdiff_t difference_type; }

  14. Concept Maps • We want to call find with an array of integers: bool contains(int* array, int n, int value) { return find(array, array + n, value) != array + n; } • Concept maps satisfy concept constraints: template<typename T> concept_map InputIterator<T*> { typedef T value_type; typedef ptrdiff_t difference_type; }

  15. Concept Refinement • A bidirectional iterator can move backward: concept BidirectionalIterator<typename Iter> : InputIterator<Iter> { Iter& operator--(Iter&); Iter operator--(Iter&, int); } • A random access iterator can jump around: concept RandomAccessIterator<typename Iter> : BidirectionalIterator<Iter> { Iter operator+(Iter, difference_type); // … } Input Iterator Bidirectional Iterator Random Access Iterator

  16. Concept-Based Overloading • Advance an iterator x by n steps: template<InputIterator Iter> void advance(Iter& x, Iter::difference_type n) { while (n > 0) { ++x; --n; } } // O(n) template<RandomAccessIterator Iter> void advance(Iter& x, Iter::difference_type n) { x = x + n; } // O(1) • Compiler selects best match: • advance(i, n); // O(1) or O(n)? • Overloaded calls in generic algorithms can cause instantiation-time ambiguities (PLDI ‘06)

  17. Concept Maps for Composition leda::GRAPH<Server, Link> internet_graph; leda::edge_array<double> total_latency; boost::shortest_paths(internet_graph, start, total_latency);

  18. Concept Maps for Composition template<typename V, typename E> concept_map Graph<leda::GRAPH<V, E> > { typedef leda::leda_node vertex_type; int num_vertices(const leda::GRAPH<V, E>& g) { return g.number_of_nodes(); } int out_degree(vertex_type v, const leda::GRAPH<V, E>&) { return outdeg(v); } };

  19. Concept Maps for Composition leda::GRAPH<Server> internet_graph; leda::edge_array<double> eigenvector; double eigenvalue = ietl::compute_eigenvector(internet_graph, eigenvector, 0);

  20. Concept Maps for Composition template<typename V, typename E> concept_map Matrix<leda::GRAPH<V, E> > { // ... };

  21. Concept Maps for Composition template<typename G> where Graph<G> concept_map Matrix<G> { // ... };

  22. Concept Maps for Composition

  23. Related Work • G • Haskell Type Classes • ML Signatures • Java, C# Generics • Fortress Traits

  24. Summary: Concepts for C++ • Concepts provide complete support for Generic Programming in C++ • Transparent composition of generic libraries • Seamless evolution of existing C++ code • Prototype implementation in ConceptGCC • Includes drop-in concept-enhanced STL http://www.generic-programming.org/software/ConceptGCC • Strong candidate for inclusion in upcoming ISO C++ Standard, C++0x

More Related