Title: Concepts for C 0x N2081
1Concepts for C0x(N2081)
Bjarne Stroustrup Texas AM University bs_at_cs.tamu.
edu
- Douglas Gregor
- Indiana University
- dgregor_at_osl.iu.edu
2What are Concepts?
- Concepts provide constrained genericity for C
templates - Make it easy to write generic functions and
classes - Make it easy to use generic functions and classes
in applications - Facilitate better code reuse and modularity
- Provide excellent performance
- Linguistic support for Generic Programming
3Why Generic Programming?
- Generic Programming is a programming methodology
for generics. - Generic Programming is the organizational
principle behind the Standard Library. - Generic Programming already has a significant
following on C.
4Design Constraints for Concepts
- Backward compatibility is important
- We cant break existing C code
- We cant change the way C works
- We need a seamless transition to concepts
- Simplicity is crucial
- Concepts should make programming better
- We need a comprehensible compilation model
- We need concepts to be implementable in
real-world compilers
5Concepts Overview
- Concepts has 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.
6Constrained 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
templatelttypename Tgt where LessThanComparableltTgt
const T min(const T x, const T y)
return x lt y? x y
7Concept Definitions
- Concept definitions state requirements on type
parameters. - auto
- concept LessThanComparablelttypename Tgt
-
- bool operatorlt(T, T)
8Signatures
- Signatures state what operations a concepts type
parameters must support - auto concept Regularlttypename Tgt
- TT()
- TT(const T)
- TT()
- T operator(T, const T)
- void swap(T, T)
9Concept Parameterization
- Concepts can have any number of parameters
- auto
- concept EqualityComparablelttypename T,
- typename U Tgt
-
- bool operator(T, U)
- bool operator!(T, U)
10Associated Types
- When we dereference an iterator, what type do we
get? - It depends on the iterator!
- concept InputIteratorlttypename Itergt
- typename value_type
- typename 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
11Using Associated Types
- Implementing the STL find with concepts
- templateltInputIterator Iter, typename Tgt
- where EqualityComparableltInputIteratorltItergtvalu
e_type, Tgt - Iter find(Iter first, Iter last, const T value)
- while (first ! last !(first value))
- first
- return first
12Concept 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 InputIteratorltintgt
- typedef int value_type
- typedef ptrdiff_t difference_type
13Constraining Associated Types
- The C Standard says
- For each iterator there is a corresponding
signed integral type called the difference type - Nested requirements place constraints on
associated types - concept InputIteratorlttypename Itergt
- typename value_type
- typename difference_type
- where SignedIntegralltdifference_typegt
- // ...
14Advancing Iterators
- Write a generic function that advances any
iterator x forward n steps - templateltInputIterator Itergt
- void advance(Iter x, Iterdifference_type n)
-
- while (n gt 0)
- x
- --n
-
15Concept Refinement
- A bidirectional iterator is an input iterator
that can move backwards - concept BidirectionalIteratorlttypename Itergt
- InputIteratorltItergt
- Iter operator--(Iter)
- Iter operator--(Iter, int)
-
- A random access iterator can jump around
- concept RandomAccessIteratorlttypename Itergt
- BidirectionalIteratorltItergt
- Iter operator(Iter, difference_type)
- //
Input Iterator
Bidirectional Iterator
Random Access Iterator
16Concept-Based Overloading
- We can overload algorithms based on concept
requirements - templateltInputIterator Itergt
- void advance(Iter x, Iterdifference_type n)
- while (n gt 0) x - -n // slow
- templateltRandomAccessIterator Itergt
- void advance(Iter x, Iterdifference_type n)
- x x n // fast!
- Compiler selects best match.
17Thinking about Stacks
- concept Stacklttypename Sgt
- typename value_type
- where Regularltvalue_typegt
- void push(S s, const value_type v)
- void pop(S s)
- const value_type top(const S s)
- bool empty(const S s)
-
18Vector as Stack
- Does vector meet the requirements of Stack?
- templateltRegular Tgt
- concept_map StackltvectorltTgtgt
- typedef T value_type
- void push(vectorltTgt vec, const value_type
value) - vec.push_back(value)
-
- void pop(vectorltTgt vec) vec.pop_back()
- const value_type top(const vectorltTgt vec)
- return vec.back()
-
- bool empty(const vectorltTgt vec) return
vec.empty()
19More Stacks
- What about list and deque?
- They also provide push_back, pop_back.
- All three containers are BackInsertionSequences
- concept BackInsertionSequencelttypename Xgt
- Regular value_type
- void Xpush_back(const value_type x)
- void Xpop_back()
- value_type Xback()
- bool Xempty() const
20Concept Maps for Concepts
- Every BackInsertionSequence is a Stack!
- templateltBackInsertionSequence Xgt
- concept_map StackltXgt
- typedef Xvalue_type value_type
- void push(X x, const value_type value)
- x.push_back(value)
-
- void pop(X x) x.pop_back()
- const value_type top(const X x)
- return x.back()
-
- bool empty(const X x) return x.empty()
21Concept Maps for Compatibility
- Iterators interact with a concept-enhanced STL
different from the existing STL - Then iterator_traits, iterator categories
- Now concept maps for iterator concepts
- Concept maps bridge the gap
- templatelttypename Itergt
- where Iter_traitsltItergt
- ConvertibleltIter_traitsltItergtiterator_catego
ry, - input_iterator_taggt
- concept_map InputIteratorltItergt late_check ...
22Conceptualizing the Library
- Formalizes much of the Standard Library
- Templates -gt Constrained Templates
- Requirements Tables -gt Concepts
- Traits -gt Concepts
- Ad hoc requirements -gt Concepts
- Guarantees about classes -gt Concept maps
- Well end up with a tighter, clearer
specification of the Standard Library.
23Implementation Status
- Prototype compiler ConceptGCC
- Based on GCC 4.1.1
- Sources, binaries available at
- www.generic-programming.org/software/ConceptGCC/
- Implements majority of N2081
- Contains a concept-enhanced STL
- Vastly better error messages than plain GCC
- Library templates fully type-checked
- Performance is within 10 of GCC 4.1.1
24Type Checking Templates
- templateltInputIterator Iter, typename Tgt
- where EqualityComparableltItervalue_type, Tgt
- Iterdifference_type
- count(Iter first, Iter last, const T value)
-
- Iterdifference_type result 0
- while (first lt last)
- if (first value) result
- return result
-
25Improved error messages
/c/4.0.1/bits/stl_algo.h In function 'void
stdsort(_Iter, _Iter) with _Iter
std_List_iteratorltintgt' sort.cpp8
instantiated from here .../c/4.0.1/bits/stl_algo
.h2852 error no match for 'operator-' in
'__last - __first' .../c/4.0.1/bits/stl_algo.h
In function 'void std__final_insertion_sort(_Ite
r, _Iter) with _Iter std_List_iteratorltintgt'
.../c/4.0.1/bits/stl_algo.h2853
instantiated from 'void stdsort(_Iter, _Iter)
with _Iter std_List_iteratorltintgt' sort.cpp
8 instantiated from here .../c/4.0.1/bits/stl
_algo.h2465 error no match for 'operator-' in
'__last - __first' .../c/4.0.1/bits/stl_algo.h2
467 error no match for 'operator' in '__first
16' .../c/4.0.1/bits/stl_algo.h2468 error
no match for 'operator' in '__first
16' .../c/4.0.1/bits/stl_algo.h In function
'void std__insertion_sort(_Iter, _Iter) with
_Iter std_List_iteratorltintgt' .../c/4.0.1/
bits/stl_algo.h2471 instantiated from 'void
std__final_insertion_sort(_Iter, _Iter) with
_Iter std_List_iteratorltintgt' .../c/4.0.1/b
its/stl_algo.h2853 instantiated from 'void
stdsort(_Iter, _Iter) with _Iter
std_List_iteratorltintgt' sort.cpp8
instantiated from here .../c/4.0.1/bits/stl_algo
.h2377 error no match for 'operator' in
'__first 1' .../c/4.0.1/bits/stl_algo.h2471
instantiated from 'void std__final_insertion_s
ort(_Iter, _Iter) with _Iter
std_List_iteratorltintgt' .../c/4.0.1/bits/stl_
algo.h2853 instantiated from 'void
stdsort(_Iter, _Iter) with _Iter
std_List_iteratorltintgt' sort.cpp8
instantiated from here .../c/4.0.1/bits/stl_algo
.h2383 error no match for 'operator' in '__i
1'
void f() listltintgt l sort(l.begin(),
l.end())
26Concepts Literature
- N2081 Concepts (Revision 1)
- Concepts Linguistic Support for Generic
Programming in C (OOPSLA 06) - Concepts for the C0x Standard Library
- N2036 Approach
- N2037 Introduction
- N2082 Utilities
- N2085 Containers
- N2083 Iterators
- N2084 Algorithms
- N2041 Numerics
- Implementation details
- N1848 Implementing Concepts
27The Concepts Crew
Douglas Gregor
Bjarne Stroustrup
Jeremiah Willcock
Ronald Garcia
28Things Were Still Working On
- Use patterns or signatures?
- What is the right granularity for late_check?
- Name lookup in where clauses.
- Unifying refinement and nested requirements?
- Are constraints absolutely necessary?
29Summary Concepts Provide...
- A natural way to express the requirements of
templates - Complete type checking for templates
- Find errors at template definition time
- Improve error messages for template uses
- Concept-based overloading
- Concept maps for adapting syntax
30(More) Questions?
31- auto concept EqualityComparablelttypename T,
- typename U Tgt
-
- bool operator(T, U)
- axiom Reflexivity(T x) x x
- axiom Symmetry(T x, T y) if (x y) y x
- axiom Transitivity(T x, T y, T z)
- if (x y y z) x z
-
32auto Concepts
- auto concepts automatically generate concept
maps, when needed - auto concept LessThanComparablelttypename Tgt
- bool operatorlt(T, T)
-
- templatelttypename Tgt
- where LessThanComparableTgt
- const T min(const T x, const T y)
- return x lt y? x y
-
- min(17, 42) // okay!
33Concept Semantics
- Axioms state the semantics of concepts
- auto concept EqualityComparablelttypename Tgt
- bool operator(T x, T y)
- axiom Symmetry(T x, T y) if (x y) y x
- axiom Reflexivity(T x) x x
- axiom Transitivitity(T x, T y, T z)
- if (x y y z) x z
-
34OR Constraints
- OR constraints allow an incoming parameter to
fulfill one of two different requirements, e.g., - templatelttypename Tgt
- where IntegralltTgt FloatingltTgt
- T abs(T x)
- return x lt 0? -x x
-
- Note that it is an error to fulfill both
constraints in an OR
35NOT Constraints
- NOT constraints are satisfied when a particular
concept map does not exist. - Used to direct concept-based overloading
- templatelttypename InIter, typename OutItergt
- where InputIteratorltInItergt
- OutputIteratorltOutIter,
InItervalue_typegt - CopyConstructibleltInItervalue_typegt
- !ForwardIteratorltInItergt
- OutIter unique_copy(InIter f, InIter l, OutIter
out) - templatelttypename InIter, typename OutItergt
- where ForwardIteratorltInItergt
- OutputIteratorltInItervalue_typegt
- OutIter unique_copy(InIter f, InIter l, OutIter
out)
36The SameType Concept
- The C Standard says
- For a Container X, Xiterator iterator type
whose value type is T - The SameType concept states that two types are
the same - concept Containerlttypename Cgt
- typename value_type Cvalue_type
- InputIterator iterator
- where SameTypeltiteratorvalue_type,
value_typegt -
37Almost Separate Type Checking
- Specialization opens up a hole in the type
system. - Consider this code
- templateltCopyConstructible Tgt
- void fun(vectorltTgt vec)
- T first vec.front()
-
- Call it with a vectorltintgt okay
- Call it with a vectorltboolgt instantiation-time
error
38The Escape Hatch
- Concepts cant model everything we do with
templates. - late_check lets us escape to do unsafe things
in a constrained template - typedef late_check typename unsafe_transformltGgtt
ype transformed_type - where Graphlttransformed_typegt
- transformed_type transformed_graph(g)
39Where Without the Template
- A where clause can be placed on a member of a
template - templateltCopyConstructible Tgt
- class list
- public
- where LessThanComparableltTgt void sort()