1 / 32

ConceptClang : An Implementation of C++ Concepts in Clang

ConceptClang : An Implementation of C++ Concepts in Clang. Larisse Voufo , Marcin Zalewski , and Andrew Lumsdaine Open Systems Lab, Indiana University. Designing Concepts in C++. Concepts are the basis of generic programming C++ does not have concepts language feature

najila
Download Presentation

ConceptClang : An Implementation of C++ Concepts in Clang

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. ConceptClang: An Implementation of C++ Concepts in Clang Larisse Voufo, MarcinZalewski, and Andrew Lumsdaine Open Systems Lab, Indiana University

  2. Designing Concepts in C++ • Concepts are the basis of generic programming • C++ does not have concepts language feature • Generic programming uses templates • Concepts were proposed but not accepted for C++11 • Insufficient implementation experience • ConceptGCC was the only prototypeavailable

  3. ConceptClang Goals: • An Infrastructure for Implementing Concepts: • In Clang • Extensible and easily accessible • Independent from any “Concepts” proposal. • “Texas”, “Indiana”, Other? • Adaptable to any proposal. • An implementation based on pre-Frankfurt standard draft.

  4. Clang: • What: • LLVM Front-end for the C family of Languages • Why: • Carefully designed coding guidelines. • Modern C++ implementation technology • Highly structured code • Easily understandable • Modular—Library-based approach • License allows extension and experimentation

  5. Templates: Example • Template Definition: • Template Use: • traverse a range and accumulate its elements • Need: an iterator, a binary operation template<typenameInputIterator, typenameT, typenameBinaryFunction> Taccumulate(InputIterator first, InputIteratorlast, Tinit, BinaryFunctionbin_op) { for (; first != last; ++first) init= bin_op(init, *first); return init; } vector<int> v; inti = accumulate(v.begin(), v.end(), 0, plus<int>());

  6. Templates: Mechanism Template Definition: Template Use: Specialization: Instantiation: template<typenameInputIterator, typenameT, typenameBinaryFunction> Taccumulate(…) { … } int accumulate(vector<int>::iterator first, vector<int>::iterator last, intinit, plus<int> bin_op); Type-Check Once! vector<int> v; inti= accumulate<vector<int>::iterator, int, plus<int> > (v.begin(), v.end(), 0, plus<int>()); int accumulate (vector<int>::iterator first, vector<int>::iterator last, intinit, plus<int> bin_op) { … }

  7. Concepts in C++: Explicit Support • Constrained Templates: • Concept Definitions: • Concept Models template<typenameI, typenameT, typenameBinOp> requires (InputIterator<I>, BinaryFunction<BinOp>) Taccumulate(Ifirst, Ilast, Tinit, BinOpbin_op) { for (; first != last; ++first) init= bin_op(init, *first); return init; } concept InputIterator<typename T>{ typenamevalue_type; T operator++(T); } concept BinaryFunction<class BinOp>{ … } concept_mapInputIterator<vector<int>::iterator> { typedefintvalue_type; T operator++(T t) { … } } concept_mapBinaryFunction<plus<int> >{ … } Modeling Mechanisms may Differ… Notion Of Models Prevails.

  8. Constrained Templates: Mechanism Constrained Template Definition: Constrained Template Use: Specialization: Instantiation: template<typenameI, typenameT, typenameBinOp> requires(InputIterator<I>, BinaryFunction<BinOp>) Taccumulate(…) { … } int accumulate(vector<int>::iterator first, vector<int>::iterator last, intinit, plus<int> bin_op); Type-check + Constraint-check Once! vector<int> v; inti= accumulate<vector<int>::iterator, int, plus<int> > (v.begin(), v.end(), 0, plus<int>()); int accumulate (vector<int>::iterator first, vector<int>::iterator last, intinit, plus<int> bin_op) { … }

  9. Templates:From Unconstrained to Constrained • Poor error detection and diagnosis: • Point to internals of library • Lengthy, hard-to-understand • WORSE: Semantic errors are not detected • Language “tricks”: • too complex, error-prone, and limited • NEED: Separate type-checking! • Errors detected at source • Diagnoses indicate exact source • Without leaking implementation details • Clang pretty-prints • Separate type-checking • We know who to blame!

  10. Templates: Problem – Example 1 Templates: Solution – Example 1 • Template Use: • Compiler error: vector<void*> v; inti = accumulate(v.begin(), v.end(), 0, plus<int>()); Larisse-Voufos-MacBook-Pro:Experimentsannlarysm$ g++ accumulate.cpp -o accumulate /usr/include/c++/4.2.1/bits/stl_numeric.h: In function ‘_Tpstd::accumulate(_InputIterator, _InputIterator, _Tp, _BinaryOperation) [with _InputIterator = __gnu_cxx::__normal_iterator<void**, std::vector<void*, std::allocator<void*> > >, _Tp = int, _BinaryOperation = std::plus<int>]’: accumulate.cpp:23: instantiated from here /usr/include/c++/4.2.1/bits/stl_numeric.h:115: error: invalid conversion from ‘void*’ to ‘int’ /usr/include/c++/4.2.1/bits/stl_numeric.h:115: error: initializing argument 2 of ‘_Tpstd::plus<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = int]’ Larisse-Voufos-MacBook-Pro:Experimentsannlarysm$ ~/llvm.test/llvm/Debug+Asserts/bin/clang++ accumulate.cpp -o accumulate accumulate.cpp:40:10: error: no matching function for call to 'accumulate' inti = accumulate(v.begin(), v.end(), 0, plus<int>()); ^~~~~~~~~~ accumulate.cpp:21:3: note: candidate template ignored: constraints check failure [with I = __gnu_cxx::__normal_iterator<void **, std::vector<void *, std::allocator<void *> > >, T = int, BinOp = std::plus<int>] T accumulate(I first, I last, T init, BinOpbin_op) { ^ accumulate.cpp:20:24: note: Concept map requirement not met. requires (InputIterator<I>, BinaryFunction<BinOp>) ^ accumulate.cpp:20:1: note: Constraints Check Failed: accumulate. requires (InputIterator<I>, BinaryFunction<BinOp>) ^ 1 error generated. Incompatible Binary Operator!

  11. Templates: Solution – Example 2 Templates: Problem – Example 2 • Template Use: • Compiler error: vector<int> v; sort(v.begin(), v.end(), not_equal_to<int>()); Larisse-Voufos-MacBook-Pro:Experimentsannlarysm$ ~/llvm.test/llvm/Debug+Asserts/bin/clang++ accumulate.cpp -o accumulate accumulate.cpp:44:2: error: no matching function for call to 'sort' sort(v.begin(), v.end(), not_equal_to<int>()); ^~~~ accumulate.cpp:34:6: note: candidate template ignored: constraints check failure [with I = __gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >, BinOp = std::not_equal_to<int>] void sort(I first, I last, BinOp comp) { ^ accumulate.cpp:33:31: note: Concept map requirement not met. requires (RandomAccessIterator<I>, StrictWeakOrdering<BinOp>) ^ accumulate.cpp:33:1: note: Constraints Check Failed: sort. requires (RandomAccessIterator<I>, StrictWeakOrdering<BinOp>) ^ 1 error generated. (None !?) Not Valid Ordering!

  12. Concepts (in C++): Essential Elements • Concept Definitions • Concept refinements • Associated declarations • Concept Modeling • Concept models • Implementations • Generic Algorithm Definition: • Constrained templates • Constrained environments • Generic Algorithm Use: • Type-checking, extended • Constraint-check  Gathers models for constraints • Models for constraints • Stored with specialization

  13. Implementation Considerations: General • Concept Definitions • Scoping checks • Lookup in refinements and associated requirements • Concept Modeling • Scoping checks • Check: model vs. concept • Lookup in concept • Generic Algorithm Definition: • Check: constraints validity • Check: body vs. constraints • Lookup in constraints • Generic Algorithm Use: • Constraint-check • Gather models for constraints • Store models for constraints • with Specialization – How?

  14. Implementation Considerations: Across Different Proposals • Concept Definitions • Non-dependence checks • Lookup in refinements and associated requirements • Concept Modeling • Non-dependence checks • Check: model vs. concept • Lookup in concept • Generic Algorithm Definition: • Check: constraints validity • Check: body vs. constraints • Lookup in constraints • Generic Algorithm Use: • Constraint-check • Gather models for constraints • Store models for constraints • With specialization – How? • Instantiation Stronger vs. Weaker Constraints? Pseudo-signatures vs. Valid Expressions? Infrastructure Layer: No Difference! Implicit vs. Explicit Modeling? How and Where?

  15. ConceptClang Implementation • Concept Definitions • All Declarations in ConceptDecl class • Name lookup, modified. • Concept Modeling • All Declarations in ConceptMapDecl class • Check: model vs. concept • Concept map generation procedure • Name lookup, modified • Generic Algorithm Definition: • Check: constraints validity • Concept map archetypes: represent constraints • Check: body vs. constraints • Name Lookup, modified • Generic Algorithm Use: • Constraint-check procedure • Returns models for constraints • Store models for constraints • In structure for specialization. • Instantiation • Rebuild declaration references

  16. ConceptClang Implementation • Concept Definitions • All Declarations in ConceptDecl class • Name Lookup, modified. • Concept Modeling • All Declarations in ConceptMapDecl class • Check: model vs. concept • Concept map generation procedure • Name Lookup, modified • Generic Algorithm Definition: • Check: constraints validity • Concept map archetypes: represent constraints • Check: body vs. constraints • Name Lookup, modified • Generic Algorithm Use: • Constraint-check procedure • Returns models for constraints • Store models for constraints • In structure for specialization. • Instantiation • Rebuild declaration references

  17. ConceptClang Implementation:Modified Lookup • Scope flags: control lookup • e.g. DeclScope  parsing a context with multiple declarations • New scope flags: • ConceptDefnScope • ConceptMapScope • RestrictedScope • Restricted- InstantiationScope

  18. ConceptClang Implementation • Concept Definitions • All Declarations in ConceptDecl class • Name Lookup, modified. • Concept Modeling • All Declarations in ConceptMapDecl class • Check: model vs. concept • Concept map generation procedure • Name Lookup, modified • Generic Algorithm Definition: • Check: constraints validity • Concept map archetypes: represent constraints • Check: body vs. constraints • Name Lookup, modified • Generic Algorithm Use: • Constraint-check procedure • Returns models for constraints • Store models for constraints • In structure for specialization. • Instantiation • Rebuild declaration references Mutual Recursion

  19. Constraints Check Procedure Constrained Template Definition: Constrained Template Use: Specialization: Maps for Constraints: • Found or generated template<typenameI, typenameT, typenameBinOp> requires(InputIterator<I>, BinaryFunction<BinOp>) Taccumulate(…) { … } int accumulate(vector<int>::iterator first, vector<int>::iterator last, intinit, plus<int> bin_op); Type-Check Constraints-Check vector<int> v; inti= accumulate<vector<int>::iterator, int, plus<int> > (…); InputIterator<vector<int>:: iterator>, BinaryFunction<plus<int> >

  20. Concept Map Generation:Satisfying Concept Refinements Concept Definition: Parsed Model Definition: Final Model Implementation: Refinement maps: concept ForwardIterator <typenameI> : InputIterator<I>, OutputIterator<I>{ … } concept_map ForwardIterator <vector<int>::iterator>{ … } Type-Check Constraints-Check concept_mapForwardIterator <vector<int>::iterator>{ … } InputIterator <vector<int>::iterator>, OutputIterator <vector<int>::iterator>

  21. Concept Map Template Generation:Satisfying Concept Refinements Concept Definition: Parsed Model Definition: Final Model Implementation: Refinement maps: concept ForwardIterator <typenameI> : InputIterator<I>, OutputIterator<I>{ … } concept_map ForwardIterator <vector<int>::iterator>{ … } Type-Check Constraints-Check template<typenameIter> requires (InputIterator<Iter>, OutputIterator<Iter>) concept_mapForwardIterator<Iter>{ … } InputIterator<Iter>, OutputIterator<Iter>

  22. ConceptClang Implementation:References to Associated Declarations • Concept Definitions • All Declarations in ConceptDecl class • Name Lookup, modified. • Concept Modeling • All Declarations in ConceptMapDecl class • Check: model vs. concept • Concept map generation procedure • Name Lookup, modified • Generic Algorithm Definition: • Check: constraints validity • Concept map archetypes: represent constraints • Check: body vs. constraints • Name Lookup, modified • Generic Algorithm Use: • Constraint-check procedure • Returns models for constraints • Store models for constraints • In structure for specialization. • Instantiation • Rebuild declaration references

  23. ConceptClang Implementation:References to Associated Declarations Template Definition: PARSING Template Specialization: INSTANTIATION template<typename T,…> requires(C<T,…>,…) void func(T a,…) { … foo(…); … } void func(int a,…); void func(int a,…) { … foo(…); … } concept_mapC<T,…> { … foo(…); … } … concept_mapC<int,…> { … foo(…); … } …

  24. ConceptClang Implementation:References to Constrained Templates • Similar to concept map templates generation • Constraints of calling context == template constraints • Parsing + Rebuilding call expression.

  25. ConceptClang Implementation:References to Constrained Templates Template Definitions: Temporary Template Specialization: PARSING Template Specializations: INSTANTIATION template<typename T,…> requires(C<T,…>,…) void oth_func(T a,…); void oth_func(int a,…); void func(int a,…); template<typename T,…> requires(CD<T,…>,…) void func(T a,…) { … oth_func(a,…); … } void func(int a,…) { … oth_func(a,…); … } concept_mapC<int,…>; … void oth_func(T a,…); concept_mapCD<int,…>; … concept_mapC<T,…>; …

  26. ConceptClang Implementation • Reusability and automation • Clang implementation is reused: • Type substitution • Type deduction • Parsing mechanism • Scoping • Unique identification • Concept Definitions • All Declarations in ConceptDecl class • Name Lookup, modified. • Concept Modeling • All Declarations in ConceptMapDecl class • Check: model vs. concept • Concept map generation procedure • Name Lookup, modified • Generic Algorithm Definition: • Check: constraints validity • Concept map archetypes: represent constraints • Check: body vs. constraints • Name Lookup, modified • Generic Algorithm Use: • Constraint-check procedure • Returns models for constraints • Store models for constraints • In structure for specialization. • Instantiation • Rebuild declaration references

  27. Essential Data Structures Scope: DeclScope | ConceptDeclScope | RestrictedScope ConceptDecl Concept Parameters TemplateDecl Template Parameters DeclContext FoldingSetNode ConceptMapDecl Template Parameters ≠ 0, for concept map templates Scope: DeclScope | ConceptMapScope | RestrictedScope Decl … NamedDecl Name

  28. ConceptClang Implementation • Concept Definitions • All Declarations in ConceptDecl class • Name Lookup, modified. • Concept Modeling • All Declarations in ConceptMapDecl class • Check: model vs. concept • Concept map generation procedure • Name Lookup, modified • Generic Algorithm Definition: • Check: constraints validity • Concept map archetypes: represent constraints • Check: body vs. constraints • Name Lookup, modified • Generic Algorithm Use: • Constraint-check procedure • Returns models for constraints • Store models for constraints • In structure for specialization. • Instantiation • Rebuild declaration references

  29. Concept-based overloading //#1 template <class FI> FI min_element(FI first, FI last); //#2 template <class T> T* min_element(T* first, T* last); //Instantiation chooses #2 int *p1, *p2; int* p = min_element(p1, p2); //#1 template <class FI> FI min_element(FI first, FI last); //#2 template <class FI> requires ForwardIterator<FI> FI min_element(FI first, FI last); //#3 template <class RI> requires RandomAccessIterator<RI> RI min_element(RI first, RI last); concept_mapForwardIterator<int*>; concept_mapRandomAccessIterator<int*>; //Instantiation chooses #3 int *p1, *p2; int* p = min_element(p1, p2); • Function Overloading: • Partial order on functions • Select most specialized function • Concept-based Overloading: • Constraints resolve ambiguities • Select most constrained as well • Question: Given functions A and B, when: • A is more constrained than B, and • B is more specialized than A • Select which one? //#B template <class T> T* min_element(T* first, T* last); //#A template <class FI> requires ForwardIterator<FI> FI min_element(FI first, FI last); concept_mapForwardIterator<int*>; //Instantiation chooses ??? int *p1, *p2; int* p = min_element(p1, p2);

  30. Concept-based overloading • Question: Given functions A and B, when: • A is more constrained than B, and • B is more specialized than A • Select which one? • Answer: • Pre-Frankfurt C++: B • ConceptClang: A • Right answer? Open question! //#B template <class T> T* min_element(T* first, T* last); //#A template <class FI> requires ForwardIterator<FI> FI min_element(FI first, FI last); concept_mapForwardIterator<int*>; //Instantiation chooses ??? int *p1, *p2; int* p = min_element(p1, p2);

  31. Practical Example: Mini-BGL template<typename G, typename C, typenameVis, typenameQType> requires (VertexListGraph<G>, IncidenceGraph<G>, ReadWriteMap<C>, SameType<ReadMap<C>::key, Graph<G>::vertex>, Color<ReadMap<C>::value>, Visitor<Vis, G>, Bag<Qtype>) voidgraph_search(const G& g, vertex s, Vis vis, C c, Qtype& Q); template<typename G, typename C, typename Vis> requires (VertexListGraph<G>, IncidenceGraph<G>, ReadWriteMap<C>, SameType<ReadMap<C>::key, Graph<G>::vertex>, Color<ReadMap<C>::value>, BFSVisitor<Vis, G>) voidbreadth_first_search(const G& g, vertex s, C c, Vis vis) { pair<vertex_iter, vertex_iter> iter_pair = vertices(g); for(vertex_iteriter = iter_pair.first, iter_end= iter_pair.second; iter != iter_end; ++iter) { vertex u = *iter; initialize_vertex(vis, u, g); set(c, u, white()); } std::queue<int> Q; graph_search(g, s, vis, c, Q); }

  32. Thank You! Questions? http://www.generic-programming.org/software/ConceptClang/ template <typename G, typename C, typename Vis> requires (VertexListGraph<G>, IncidenceGraph<G>, ReadWriteMap<C>, SameType<ReadMap<C>::key, Graph<G>::vertex>, Color<ReadMap<C>::value>, BFSVisitor<Vis, G>) voidbreadth_first_search(const G& g, vertex s, C c, Vis vis) { pair<vertex_iter, vertex_iter> iter_pair = vertices(g); for(vertex_iteriter = iter_pair.first, iter_end= iter_pair.second; iter != iter_end; ++iter) { vertex u = *iter; initialize_vertex(vis, u, g); set(c, u, white()); } std::queue<int> Q; graph_search(g, s, vis, c, Q); }

More Related