+ All Categories
Home > Documents > Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary...

Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary...

Date post: 29-Jul-2020
Category:
Upload: others
View: 1 times
Download: 0 times
Share this document with a friend
98
Boost.Generic: Concepts without Concepts Matt Calabrese Boost.Generic: Concepts without Concepts © 2011 Matt Calabrese 1/98
Transcript
Page 1: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Boost.Generic:Concepts without Concepts

Matt Calabrese

Boost.Generic: Concepts without Concepts © 2011 Matt Calabrese 1/98

Page 2: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Overview What is Generic Programming?

The End of C++0x Concepts

Substitution Failure Is Not an Error

A Brief History of Boost.Generic

The Necessary Tools

Built-in Concepts and Asserts

Creating Concepts

Creating Concept Maps

Future Direction

Questions

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 2/98

Page 3: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

What is Generic Programming?

You Tell Me

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 3/98

Page 4: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

What is Generic Programming?

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 4/98

Programming Paradigm

Stepanov and Musser

STL, BGL, Boost.GIL, etc.

Algorithm-Centric

Lifting

Requirements/Constraints

Multi-Sorted Algebras

Refinement

Concept Mapping

Archetypes

Concept-Based Overloading

Page 5: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

The End of C++0x Concepts

Can't We All Just Get Along?

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 5/98

Page 6: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

The End of C++0x Concepts

Indiana Proposal IU – Siek, Gregor, Garcia, Willcock, Järvi, Lumsdaine Explicit Concepts by Default Allow “Auto” Concepts Concept Maps

Texas Proposal Texas A&M – Bjarne Stroustrup, Gabriel Dos Rei All Concepts are Automatic No Explicit Concept Maps

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 6/98

Page 7: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Substitution Failure Is Not an Error

Or Is It!?*

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 7/98

*No, really, I'm not lying. It's not an error.

Page 8: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Substitution Failure Is Not an Error

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 8/98

What is SFINAE?

int negate(int i) { return -i; }

template <class F> typename F::result_type negate(const F& f) { return -f(); }

int neg1 = negate( 1 );

Page 9: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Substitution Failure Is Not an Error

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 9/98

Boost.Enable_If

template< bool B, class T = void > struct enable_if_c { typedef T type; };

template< class T > struct enable_if_c<false, T> {}

template< bool B, class T = void > struct disable_if_c : enable_if_c< !b, T > {};

template< class T > typename enable_if< has_trivial_destructor< T >::value >::type foo( T& bar ) { … }

template< class T > typename disable_if< has_trivial_destructor< T >::value >::type foo( T& bar ) { … }

Page 10: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

A Brief History of Boost.Generic

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts

Or: How I Learned to Stop Worrying and

Love the Preprocessor

10/98

Page 11: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

A Brief History of Boost.GenericIt all began with C++0x “auto” functions...

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts

What should the return type be?

template< class L, class R > ??? operator -( L lhs, R rhs ) { return lhs + -rhs; }

11/98

Page 12: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

A Brief History of Boost.GenericIt all began with C++0x “auto” functions...

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts

template< class L, class R > auto operator -( L lhs, R rhs ) -> decltype( lhs + -rhs ) { return lhs + -rhs; }

12/98

Page 13: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

A Brief History of Boost.GenericIt all began with C++0x “auto” functions...

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts

template< class L, class R > auto operator -( L lhs, R rhs ) -> decltype( lhs + -rhs ) { return lhs + -rhs; }

But isn't this redundant?

13/98

Page 14: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

A Brief History of Boost.GenericIt all began with C++0x “auto” functions...

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts

template< class L, class R > auto operator -( L lhs, R rhs ) -> decltype( lhs + -rhs ) { return lhs + -rhs; }

But isn't this redundant?

auto minus = []( L lhs, R rhs ) { return lhs + -rhs; };

Lambdas can deduce return types without redundancy.

14/98

Page 15: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

A Brief History of Boost.Generic

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts

Ahh... much better!

template< class L, class R > BOOST_AUTO_FUNCTION( operator -( L lhs, R rhs ) ) ( return lhs + -rhs )

Macros save the day!

15/98

Page 16: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

A Brief History of Boost.Generic

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts

But how would we use enable_if here?*

template< class L, class R > BOOST_AUTO_FUNCTION( operator -( L lhs, R rhs ) ) ( return lhs + -rhs )

*In the world of C++0x before discovering the new way to use enable_if

Macros save the day!

Ahh... much better!

16/98

Page 17: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

A Brief History of Boost.Generic

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts

template< class L, class R > BOOST_AUTO_FUNCTION( operator -( L const& lhs, R const& rhs ) , if ( is_vector_udt< L > ) ( is_vector_udt< R > ) ) ( return lhs + -rhs )

More complicated macros, of course!

17/98

Page 18: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

A Brief History of Boost.Generic

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts

template< class L, class R > BOOST_AUTO_FUNCTION( operator -( L const& lhs, R const& rhs ) , if ( is_vector_udt< L > ) ( is_vector_udt< R > ) , try ( lhs + rhs ) ( -rhs ) , if typename ( L::value_type ) ) ( return lhs + -rhs )

Okay, stop it already!

18/98

Page 19: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

A Brief History of Boost.Generic

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts

What if we used these ideas to make a macro for specifying concepts...

19/98

[utility.arg.requirements]...In these tables, T is an object or reference type to be supplied by a C++ program instantiating a template; a, b, and c are values of type (possibly const) T...

Page 20: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

A Brief History of Boost.Generic

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts

BOOST_GENERIC_AD_HOC_CONCEPT ( (EqualityComparable)( (class) T ) , ( for ( (T const) a ) ( (T const) b ) ) , ( try ( a == b ) ) , ( if ( is_convertible< decltype( a == b ), bool > ) ) )

What if we used these ideas to make a macro for specifying concepts...

20/98

[utility.arg.requirements]...In these tables, T is an object or reference type to be supplied by a C++ program instantiating a template; a, b, and c are values of type (possibly const) T...

Page 21: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

A Brief History of Boost.Generic

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts

BOOST_GENERIC_AD_HOC_CONCEPT ( (EqualityComparable)( (class) T ) , ( for ( (T const) a ) ( (T const) b ) ) , ( try ( a == b ) ) , ( if ( is_convertible< decltype( a == b ), bool > ) ) )

What if we used these ideas to make a macro for specifying concepts...

21/98

[utility.arg.requirements]...In these tables, T is an object or reference type to be supplied by a C++ program instantiating a template; a, b, and c are values of type (possibly const) T...

Page 22: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

The Necessary Tools

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 22/98

What Can Be Accomplishedand How

Page 23: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

The Necessary Tools

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 23/98

Overall Goals

Represent Concepts as Closely as Possible to N2914

Support the Major Features of Concepts

Keep the Error Messages Simple (Simpler than BCCL)

Automatically Generate Archetypes

Support Concept Overloading

Allow a Choice of Backends

Implement the Standard Concepts

Minimize the Pain Inflicted on Compilers

Page 24: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

The Necessary Tools

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 24/98

Overall Goals

Represent Concepts as Closely as Possible to N2914

Support the Major Features of Concepts

Keep the Error Messages Simple (Simpler than BCCL)

Automatically Generate Archetypes

Support Concept Overloading

Allow a Choice of Backends

Implement the Standard Concepts

Minimize the Pain Inflicted on Compilers (Just Kidding)

Page 25: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

The Necessary Tools

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 25/98

C++ 0x Syntax concept ArithmeticLike<typename T> : Regular<T>, LessThanComparable<T>, HasUnaryPlus<T>, HasNegate<T>, HasPlus<T, T>, HasMinus<T, T>, … { explicit T::T(intmax_t); explicit T::T(uintmax_t); explicit T::T(long double); requires Convertible<HasUnaryPlus<T>::result_type, T>; … }

Page 26: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

The Necessary Tools

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 26/98

C++ 0x Syntax concept ArithmeticLike<typename T> : Regular<T>, LessThanComparable<T>, HasUnaryPlus<T>, HasNegate<T>, HasPlus<T, T>, HasMinus<T, T>, … { explicit T::T(intmax_t); explicit T::T(uintmax_t); explicit T::T(long double); requires Convertible<HasUnaryPlus<T>::result_type, T>; … }

BOOST_GENERIC_CONCEPT ( (ArithmeticLike)( (typename) T ) , ( public Regular<T>, LessThanComparable<T>, HasUnaryPlus<T>, HasNegate<T>, HasPlus<T, T>, HasMinus<T, T>, … ) , ( explicit (this(T))( (intmax_t) ) ) , ( explicit (this(T))( (uintmax_t) ) ) , ( explicit (this(T))( (long double) ) ) , ( requires Convertible<typename HasUnaryPlus<T>::result_type, T> ) , … )

Hypothetical Macro Syntax

Page 27: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

The Necessary Tools

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts

Just what can be accomplished (not a complete list)?

Language-Level Concepts

Library-Based Concept Support

Associate Types Yes

Associate Functions Yes

Multi-type Concepts Yes

Concept Maps Yes

Archetypes Yes

Concept Refinement ???

Typename Deduction ???

Concept-Based Overloading ???

27/98

Page 28: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

The Necessary Tools

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 28/98

template< unsigned Val = 256 > struct num_elem : num_elem< Val - 1 > {}; template<> struct num_elem< 0 > {};

template< class Tag, class ThisElem = void, class OtherHolder = void > struct type_seq_holder { static unsigned const value = OtherHolder::value + 1; static num_elem< value + 1 > next_index(); typedef typename push_back< typename OtherHolder::type_seq, ThisElem >::type type_seq; };

template< class Tag > struct type_seq_holder< Tag > { static unsigned const value = 0; static num_elem< 1 > next_index(); typedef vector<> type_seq; };

template< class Tag > type_seq_holder< Tag > get_type_seq_holder( Tag, num_elem< 0 > const& );

#define ADD_TO_LIST( list_tag, new_elem )\ type_seq_holder< list_tag, new_elem, decltype( get_type_seq_holder( list_tag(), num_elem<>() ) ) >\ get_type_seq_holder\ ( list_tag, decltype( get_type_seq_holder(list_tag(), num_elem<>() ).next_index() ) const& );

#define GET_LIST( list_tag )\ identity< decltype( get_type_seq_holder( list_tag(), num_elem<>() ) ) >::type::type_seq

List of Types Across a Translation Unit

Page 29: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

The Necessary Tools

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts

Just what can be accomplished (not a complete list)?

Language-Level Concepts

Library-Based Concept Support

Associate Types Yes

Associate Functions Yes

Multi-type Concepts Yes

Concept Maps Yes

Archetypes Yes

Concept Refinement Yes

Typename Deduction ???

Concept-Based Overloading ???

29/98

Page 30: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

The Necessary Tools

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 30/98

auto concept HasFind<typename T> { typename key_type = typename T::key_type; typename mapped_type; std::pair< key_type, mapped_type > find( T const&, key_type const& ); }

struct container { typedef int key_type; }; std::pair< int, float > find( container, int );

Typename Deduction

Page 31: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

The Necessary Tools

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 31/98

auto concept HasFind<typename T> { typename key_type = typename T::key_type; typename mapped_type; std::pair< key_type, mapped_type > find( T const&, key_type const& ); }

struct container { typedef int key_type; }; std::pair< int, float > find( container, int );

Typename Deduction

Page 32: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

The Necessary Tools

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 32/98

auto concept HasFind<typename T> { typename key_type = typename T::key_type; typename mapped_type; std::pair< key_type, mapped_type > find( T const&, key_type const& ); }

struct container { typedef int key_type; }; std::pair< int, float > find( container, int );

auto concept HasDereference<typename T> { typename result_type; result_type operator*(T&); result_type operator*(T&&); }

Typename Deduction

Very Common With Auto-Concepts

Page 33: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

The Necessary Tools

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 33/98

14.10.2.2 Associated type and template definitions [concept.map.assoc]

“…A concept map member that satisfies an associated type or class template requirement can be implicitly defined using template argument deduction (14.9.2) with one or more associated function requirements (14.10.2.1), if the associated type or class template requirement does not have a default value. The definition of the associated type or class template is determined using the rules of template argument deduction from a type (14.9.2.5).

– Let P be the return type of an associated function after substitution of the concept’s template parameters specified by the concept map with their template arguments, and where each undefined associated type and associated class template has been replaced with a newly invented type or template template parameter, respectively.

– Let A be the return type of the seed in the associated function candidate set corresponding to the associated function.

If the deduction fails, no concept map members are implicitly defined by that associated function. If the results of deduction produced by different associated functions yield more than one possible value, that associated type or class template is not implicitly defined…”

Typename Deduction

Page 34: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

The Necessary Tools

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 34/98

BOOST_GENERIC_AUTO_CONCEPT ( (HasFind)( (typename) T ) , ( typename key_type, typename T::key_type ) , ( typename mapped_type ) , ( (std::pair< key_type, mapped_type >)(find)( (T const&), (key_type const&) ) ) )

Typename Deduction

Page 35: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

The Necessary Tools

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 35/98

BOOST_GENERIC_AUTO_CONCEPT ( (HasFind)( (typename) T ) , ( typename key_type, typename T::key_type ) , ( typename mapped_type ) , ( (std::pair< key_type, mapped_type >)(find)( (T const&), (key_type const&) ) ) )

Typename Deduction

Page 36: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

The Necessary Tools

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 36/98

BOOST_GENERIC_AUTO_CONCEPT ( (HasFind)( (typename) T ) , ( typename key_type, typename T::key_type ) , ( typename mapped_type ) , ( (std::pair< key_type, mapped_type >)(find)( (T const&), (key_type const&) ) ) )

Typename Deduction

typedef typename T::key_type key_type;

struct dummy_type {};

identity< dummy_type > deduce( ... );

template< class mapped_type > identity< mapped_type > deduce( identity< std::pair< key_type, mapped_type > > );

typedef decltype( deduce( identity< decltype( find( declval<T const&>(), declval<key_type const&>() ) ) >() ) ) deduce_result;

typedef typename deduce_result::type mapped_type;

Exploit Template Argument Deduction

Page 37: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

The Necessary Tools

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts

Just what can be accomplished (not a complete list)?

Language-Level Concepts

Library-Based Concept Support

Associate Types Yes

Associate Functions Yes

Multi-type Concepts Yes

Concept Maps Yes

Archetypes Yes

Concept Refinement Yes

Typename Deduction Yes

Concept-Based Overloading ???

37/98

Page 38: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

The Necessary Tools

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts

Can we use a technique similar to tag dispatching?

template< class It, class DiffT > void advance( It& it, DiffT offset ) { typedef typename std::iterator_traits< It >::iterator_category category;

advance_impl( it, offset, category() ); }

template< class It, class DiffT > void advance_impl( It& it, DiffT offset, std::input_iterator_tag ) /**/

template< class It, class DiffT > void advance_impl( It& it, DiffT offset, std::bidirectional_iterator_tag ) /**/

template< class It, class DiffT > void advance_impl( It& it, DiffT offset, std::random_access_iterator_tag ) /**/

We can start by automatically creating tags that are related by inheritance...

38/98

Page 39: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

The Necessary Tools

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts

Just what can be accomplished (not a complete list)?

Language-Level Concepts

Library-Based Concept Support

Associate Types Yes

Associate Functions Yes

Multi-type Concepts Yes

Concept Maps Yes

Archetypes Yes

Concept Refinement Yes

Typename Deduction Yes

Concept-Based Overloading Almost

39/98

Page 40: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Built-in Concepts and Asserts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 40/98

For the Lazy Programmers WhoWant Me to Do All of the Work

Page 41: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Built-in Concepts and Asserts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 41/98

Which Concepts Are Currently Implemented?

<concepts> 78/78 <container_concepts> 0/20 <iterator_concepts> 8/8 <memory_concepts> 0/6 [concept.support] 23/23

Page 42: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Built-in Concepts and Asserts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 42/98

The Basic Header Structure

// Include all built-in concepts #include <boost/generic/std_concept.hpp>

// Include all iterator concepts (akin to <iterator_concepts>) #include <boost/generic/std_concept/iterator_concepts.hpp>

// Include just the forward iterator concept and its dependencies #include <boost/generic/std_concept/iterator_concepts/forward_iterator.hpp>

// Etc.

// Include all assert macros #include <boost/generic/assert.hpp>

Concepts are based on N2914

Page 43: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Built-in Concepts and Asserts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 43/98

Concept Asserts

BOOST_GENERIC_ASSERT( HasPlus< int*, int> );

BOOST_GENERIC_ASSERT_NOT( HasPlus< int*, int* > );

// Triggers a static_assert BOOST_GENERIC_ASSERT( HasPlus< int*, int* > )

Page 44: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Built-in Concepts and Asserts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 44/98

Concept Asserts

BOOST_GENERIC_ASSERT( HasPlus< int*, int> );

BOOST_GENERIC_ASSERT_NOT( HasPlus< int*, int* > );

// Triggers a static_assert BOOST_GENERIC_ASSERT( HasPlus< int*, int* > )

has_plus.cpp:14:177: error: static assertion failed: "requires HasPlus< int*, int* >"has_plus.cpp:10:0:has_plus.hpp: In instantiation of 'boost::generic::std_concept::HasPlus<int*, int*>':has_plus.cpp:14:543: instantiated from herehas_plus.hpp:20:10224: error: static assertion failed: "typename \'result_type\' was not explicitly satisfied and cannot be deduced."has_plus.hpp: In instantiation of 'boost::generic::std_concept::HasPlus<int*, int*>':has_plus.cpp:14:543: instantiated from herehas_plus.hpp:20:10691: error: static assertion failed: "requires result_type operator +( const T& , const U& )"

Page 45: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

Enough already, I want to

make my own!

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 45/98

Page 46: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 46/98

Starting with the Basics...

namespace boost { namespace generic {

concept Foo<typename T> {}

} }

Page 47: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 47/98

Starting with the Basics...

namespace boost { namespace generic {

concept Foo<typename T> {}

} }

BOOST_GENERIC_CONCEPT ( ( namespace boost, generic ) , (Foo)( (typename) T ) )

Page 48: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 48/98

Starting with the Basics...

namespace boost { namespace generic {

concept Foo<typename T> {}

} }

BOOST_GENERIC_CONCEPT ( ( namespace boost, generic ) , (Foo)( (typename) T ) )

Page 49: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 49/98

Starting with the Basics...

namespace boost { namespace generic {

concept Foo<typename T> {}

} }

BOOST_GENERIC_CONCEPT ( ( namespace boost, generic ) , (Foo)( (typename) T ) )

Page 50: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 50/98

Starting with the Basics...

namespace boost { namespace generic {

concept Foo<typename T> {}

} }

BOOST_GENERIC_CONCEPT ( ( namespace boost, generic ) , (Foo)( (typename) T ) )

Page 51: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 51/98

Starting with the Basics...

auto concept IdentityOf<typename T> { typename type = T; requires SameType<type, T>; }

Page 52: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 52/98

Starting with the Basics...

auto concept IdentityOf<typename T> { typename type = T; requires SameType<type, T>; }

BOOST_GENERIC_AUTO_CONCEPT ( (IdentityOf)( (typename) T ) , ( typename type, T ) , ( requires SameType<type, T> ) )

Page 53: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 53/98

Starting with the Basics...

auto concept IdentityOf<typename T> { typename type = T; requires SameType<type, T>; }

BOOST_GENERIC_AUTO_CONCEPT ( (IdentityOf)( (typename) T ) , ( typename type, T ) , ( requires SameType<type, T> ) )

Page 54: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 54/98

Starting with the Basics...

auto concept IdentityOf<typename T> { typename type = T; requires SameType<type, T>; }

BOOST_GENERIC_AUTO_CONCEPT ( (IdentityOf)( (typename) T ) , ( typename type, T ) , ( requires SameType<type, T> ) )

Page 55: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 55/98

Starting with the Basics...

auto concept IdentityOf<typename T> { typename type = T; requires SameType<type, T>; }

BOOST_GENERIC_AUTO_CONCEPT ( (IdentityOf)( (typename) T ) , ( typename type, T ) , ( requires SameType<type, T> ) )

Page 56: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 56/98

Starting with the Basics...

auto concept IdentityOf<typename T> { typename type = T; requires SameType<type, T>; }

BOOST_GENERIC_AUTO_CONCEPT ( (IdentityOf)( (typename) T ) , ( typename type, T ) , ( requires SameType<type, T> ) )

Page 57: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 57/98

Starting with the Basics...

auto concept IdentityOf<typename T> { typename type = T; requires SameType<type, T>; }

BOOST_GENERIC_AUTO_CONCEPT ( (IdentityOf)( (typename) T ) , ( typename type, T ) , ( requires SameType<type, T> ) )

Page 58: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 58/98

Member Function Requirements

auto concept MemberFunctionRequirements<typename T> { void T::foo() const; T::T( int a, float b ); T::~T(); }

Page 59: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 59/98

Member Function Requirements

auto concept MemberFunctionRequirements<typename T> { void T::foo() const; T::T( int a, float b ); T::~T(); }

BOOST_GENERIC_AUTO_CONCEPT ( (MemberFunctionRequirements)( (typename) T ) , ( (void)(this(T) foo)() const ) , ( (this(T))( (int) a, (float) b ) ) , ( (this(T) destroy)() ) )

Page 60: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 60/98

Member Function Requirements

auto concept MemberFunctionRequirements<typename T> { void T::foo() const; T::T( int a, float b ); T::~T(); }

BOOST_GENERIC_AUTO_CONCEPT ( (MemberFunctionRequirements)( (typename) T ) , ( (void)(this(T) foo)() const ) , ( (this(T))( (int) a, (float) b ) ) , ( (this(T) destroy)() ) )

Page 61: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 61/98

Member Function Requirements

auto concept MemberFunctionRequirements<typename T> { void T::foo() const; T::T( int a, float b ); T::~T(); }

BOOST_GENERIC_AUTO_CONCEPT ( (MemberFunctionRequirements)( (typename) T ) , ( (void)(this(T) foo)() const ) , ( (this(T))( (int) a, (float) b ) ) , ( (this(T) destroy)() ) )

Page 62: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 62/98

Member Function Requirements

auto concept MemberFunctionRequirements<typename T> { void T::foo() const; T::T( int a, float b ); T::~T(); }

BOOST_GENERIC_AUTO_CONCEPT ( (MemberFunctionRequirements)( (typename) T ) , ( (void)(this(T) foo)() const ) , ( (this(T))( (int) a, (float) b ) ) , ( (this(T) destroy)() ) )

Page 63: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 63/98

Member Function Requirements

auto concept MemberFunctionRequirements<typename T> { void T::foo() const; T::T( int a, float b ); T::~T(); }

BOOST_GENERIC_AUTO_CONCEPT ( (MemberFunctionRequirements)( (typename) T ) , ( (void)(this(T) foo)() const ) , ( (this(T))( (int) a, (float) b ) ) , ( (this(T) destroy)() ) )

Page 64: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 64/98

Operator Requirements

auto concept HasEqualTo<typename T, typename U> { bool operator==(const T& a, const U& b); }

Page 65: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 65/98

Operator Requirements

auto concept HasEqualTo<typename T, typename U> { bool operator==(const T& a, const U& b); }

BOOST_GENERIC_AUTO_CONCEPT ( (HasEqualTo)( (typename) T, (typename) U ) , ( (bool)(operator equal_to)( (const T&) a, (const U&) b ) ) )

Page 66: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 66/98

Operator Requirements

auto concept HasEqualTo<typename T, typename U> { bool operator==(const T& a, const U& b); }

BOOST_GENERIC_AUTO_CONCEPT ( (HasEqualTo)( (typename) T, (typename) U ) , ( (bool)(operator equal_to)( (const T&) a, (const U&) b ) ) )

Page 67: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 67/98

Operator Namesplus

+greater_equal

>=complement

~minus_assign

-=preincrement

++

minus-

equal_to==

left_shift<<

multiply_assign*=

postincrement++

divide/

not_equal_to!=

right_shift>>

divide_assign/=

predecrement--

modulus%

logical_and&&

dereference*

modulus_assign%=

postdecrement--

unary_plus+

logical_or||

address_of&

bit_and_assign&=

comma,

negate-

logical_not!

subscript[]

bit_or_assign|=

newnew

less<

bit_and&

call()

bit_xor_assign^=

new_arraynew []

greater>

bit_or|

assign=

left_shift_assign<<=

deletedelete

less_equal<=

bit_xor^

plus_assign+=

right_shift_assign>>=

delete_arraydelete []

multiply*

arrow->

arrow_dereference->*

Page 68: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 68/98

Operator Namesplus

+greater_equal

>=complement

~minus_assign

-=preincrement

++

minus-

equal_to==

left_shift<<

multiply_assign*=

postincrement++

divide/

not_equal_to!=

right_shift>>

divide_assign/=

predecrement--

modulus%

logical_and&&

dereference*

modulus_assign%=

postdecrement--

unary_plus+

logical_or||

address_of&

bit_and_assign&=

comma,

negate-

logical_not!

subscript[]

bit_or_assign|=

newnew

less<

bit_and&

call()

bit_xor_assign^=

new_arraynew []

greater>

bit_or|

assign=

left_shift_assign<<=

deletedelete

less_equal<=

bit_xor^

plus_assign+=

right_shift_assign>>=

delete_arraydelete []

multiply*

arrow->

arrow_dereference->*

Page 69: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 69/98

Conversion Operation Requirements

auto concept ExplicitlyConvertible<typename T, typename U> { explicit operator U(const T&); }

auto concept Convertible<typename T, typename U> : ExplicitlyConvertible<T, U> { operator U(const T&); }

Page 70: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 70/98

Conversion Operation Requirements

auto concept ExplicitlyConvertible<typename T, typename U> { explicit operator U(const T&); }

auto concept Convertible<typename T, typename U> : ExplicitlyConvertible<T, U> { operator U(const T&); }

BOOST_GENERIC_AUTO_CONCEPT ( (ExplicitlyConvertible)( (typename) T, (typename) U ) , ( explicit (operator U)( (const T&) ) ) )

BOOST_GENERIC_AUTO_CONCEPT ( (Convertible)( (typename) T, (typename) U ) , ( public ExplicitlyConvertible<T, U > ) , ( (operator U)( (const T&) ) ) )

Page 71: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 71/98

More Complicated than It Looks

auto concept HasDereference<typename T> { typename result_type; result_type operator*(T&); result_type operator*(T&&); }

Page 72: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 72/98

More Complicated than It Looks

auto concept HasDereference<typename T> { typename result_type; result_type operator*(T&); result_type operator*(T&&); }

Page 73: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 73/98

More Complicated than It Looks

auto concept HasDereference<typename T> { typename result_type; result_type operator*(T&); result_type operator*(T&&); }

BOOST_GENERIC_AUTO_CONCEPT ( (HasDereference)( (typename) T ) , ( typename result_type ) , ( (result_type)(operator dereference)(T&) ) , ( (result_type)(operator dereference)(T&&) ) )

Page 74: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 74/98

Concept Value Parameters concept True<bool V> {} concept_map True<true> {}

auto concept IsEven<intmax_t V> { requires True<V%2==0>; }

Page 75: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 75/98

Concept Value Parameters concept True<bool V> {} concept_map True<true> {}

auto concept IsEven<intmax_t V> { requires True<V%2==0>; }

BOOST_GENERIC_CONCEPT( (True)( (bool) V ) ) …

BOOST_GENERIC_AUTO_CONCEPT ( (IsEven)( (bool) V ) , ( requires True<V%2==0> ) )

Page 76: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 76/98

Refinement and Axioms auto concept CopyConstructible<typename T> : MoveConstructible<T>, Constructible<T, const T&> { axiom CopyPreservation(T x) { T(x) == x; } }

Page 77: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 77/98

Refinement and Axioms auto concept CopyConstructible<typename T> : MoveConstructible<T>, Constructible<T, const T&> { axiom CopyPreservation(T x) { T(x) == x; } }

BOOST_GENERIC_AUTO_CONCEPT ( (CopyConstructible)( (typename) T ) , ( public MoveConstructible<T>, Constructible1<T, const T&> ) , ( axiom CopyPreservation(T x) { T(x) == x; } ) )

Page 78: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 78/98

Everybody's favorite concepts... Iterators (N2914)!!!

concept Iterator<typename X> : Semiregular<X> { MoveConstructible reference = typename X::reference; MoveConstructible postincrement_result; requires HasDereference<postincrement_result>; reference operator*(X&); reference operator*(X&&); X& operator++(X&); postincrement_result operator++(X&, int); }

Page 79: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 79/98

Everybody's favorite concepts... Iterators (N2914)!!!

concept Iterator<typename X> : Semiregular<X> { MoveConstructible reference = typename X::reference; MoveConstructible postincrement_result; requires HasDereference<postincrement_result>; reference operator*(X&); reference operator*(X&&); X& operator++(X&); postincrement_result operator++(X&, int); }

BOOST_GENERIC_CONCEPT ( (Iterator)( (typename) X ), ( public Semiregular<X> ) , ( (MoveConstructible) reference, typename X::reference ) , ( (MoveConstructible) postincrement_result ) , ( requires HasDereference<postincrement_result> ) , ( (reference)(operator dereference)( (X&) ) ) , ( (reference)(operator dereference)( (X&&) ) ) , ( (X&)(operator preincrement)( (X&) ) ) , ( (postincrement_result)(operator postincrement)( (X&), (int) ) ) )

Page 80: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 80/98

Everybody's favorite concepts... Iterators (N2914)!!!

concept Iterator<typename X> : Semiregular<X> { MoveConstructible reference = typename X::reference; MoveConstructible postincrement_result; requires HasDereference<postincrement_result>; reference operator*(X&); reference operator*(X&&); X& operator++(X&); postincrement_result operator++(X&, int); }

BOOST_GENERIC_CONCEPT ( (Iterator)( (typename) X ), ( public Semiregular<X> ) , ( (MoveConstructible) reference, typename X::reference ) , ( (MoveConstructible) postincrement_result ) , ( requires HasDereference<postincrement_result> ) , ( (reference)(operator dereference)( (X&) ) ) , ( (reference)(operator dereference)( (X&&) ) ) , ( (X&)(operator preincrement)( (X&) ) ) , ( (postincrement_result)(operator postincrement)( (X&), (int) ) ) )

Page 81: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 81/98

Everybody's favorite concepts... Iterators (N2914)!!!

concept Iterator<typename X> : Semiregular<X> { MoveConstructible reference = typename X::reference; MoveConstructible postincrement_result; requires HasDereference<postincrement_result>; reference operator*(X&); reference operator*(X&&); X& operator++(X&); postincrement_result operator++(X&, int); }

BOOST_GENERIC_CONCEPT ( (Iterator)( (typename) X ), ( public Semiregular<X> ) , ( (MoveConstructible) reference, typename X::reference ) , ( (MoveConstructible) postincrement_result ) , ( requires HasDereference<postincrement_result> ) , ( (reference)(operator dereference)( (X&) ) ) , ( (reference)(operator dereference)( (X&&) ) ) , ( (X&)(operator preincrement)( (X&) ) ) , ( (postincrement_result)(operator postincrement)( (X&), (int) ) ) )

Page 82: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 82/98

Everybody's favorite concepts... Iterators (N2914)!!!

concept Iterator<typename X> : Semiregular<X> { MoveConstructible reference = typename X::reference; MoveConstructible postincrement_result; requires HasDereference<postincrement_result>; reference operator*(X&); reference operator*(X&&); X& operator++(X&); postincrement_result operator++(X&, int); }

BOOST_GENERIC_CONCEPT ( (Iterator)( (typename) X ), ( public Semiregular<X> ) , ( (MoveConstructible) reference, typename X::reference ) , ( (MoveConstructible) postincrement_result ) , ( requires HasDereference<postincrement_result> ) , ( (reference)(operator dereference)( (X&) ) ) , ( (reference)(operator dereference)( (X&&) ) ) , ( (X&)(operator preincrement)( (X&) ) ) , ( (postincrement_result)(operator postincrement)( (X&), (int) ) ) )

Page 83: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 83/98

Everybody's favorite concepts... Iterators (N2914)!!!

concept Iterator<typename X> : Semiregular<X> { MoveConstructible reference = typename X::reference; MoveConstructible postincrement_result; requires HasDereference<postincrement_result>; reference operator*(X&); reference operator*(X&&); X& operator++(X&); postincrement_result operator++(X&, int); }

BOOST_GENERIC_CONCEPT ( (Iterator)( (typename) X ), ( public Semiregular<X> ) , ( (MoveConstructible) reference, typename X::reference ) , ( (MoveConstructible) postincrement_result ) , ( requires HasDereference<postincrement_result> ) , ( (reference)(operator dereference)( (X&) ) ) , ( (reference)(operator dereference)( (X&&) ) ) , ( (X&)(operator preincrement)( (X&) ) ) , ( (postincrement_result)(operator postincrement)( (X&), (int) ) ) )

Page 84: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 84/98

Everybody's favorite concepts... Iterators (N2914)!!!

concept Iterator<typename X> : Semiregular<X> { MoveConstructible reference = typename X::reference; MoveConstructible postincrement_result; requires HasDereference<postincrement_result>; reference operator*(X&); reference operator*(X&&); X& operator++(X&); postincrement_result operator++(X&, int); }

BOOST_GENERIC_CONCEPT ( (Iterator)( (typename) X ), ( public Semiregular<X> ) , ( (MoveConstructible) reference, typename X::reference ) , ( (MoveConstructible) postincrement_result ) , ( requires HasDereference<postincrement_result> ) , ( (reference)(operator dereference)( (X&) ) ) , ( (reference)(operator dereference)( (X&&) ) ) , ( (X&)(operator preincrement)( (X&) ) ) , ( (postincrement_result)(operator postincrement)( (X&), (int) ) ) )

Page 85: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 85/98

Everybody's favorite concepts... Iterators (N2914)!!!

concept Iterator<typename X> : Semiregular<X> { MoveConstructible reference = typename X::reference; MoveConstructible postincrement_result; requires HasDereference<postincrement_result>; reference operator*(X&); reference operator*(X&&); X& operator++(X&); postincrement_result operator++(X&, int); }

BOOST_GENERIC_CONCEPT ( (Iterator)( (typename) X ), ( public Semiregular<X> ) , ( (MoveConstructible) reference, typename X::reference ) , ( (MoveConstructible) postincrement_result ) , ( requires HasDereference<postincrement_result> ) , ( (reference)(operator dereference)( (X&) ) ) , ( (reference)(operator dereference)( (X&&) ) ) , ( (X&)(operator preincrement)( (X&) ) ) , ( (postincrement_result)(operator postincrement)( (X&), (int) ) ) )

Page 86: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 86/98

Everybody's favorite concepts... Iterators (N2914)!!!

concept Iterator<typename X> : Semiregular<X> { MoveConstructible reference = typename X::reference; MoveConstructible postincrement_result; requires HasDereference<postincrement_result>; reference operator*(X&); reference operator*(X&&); X& operator++(X&); postincrement_result operator++(X&, int); }

BOOST_GENERIC_CONCEPT ( (Iterator)( (typename) X ), ( public Semiregular<X> ) , ( (MoveConstructible) reference, typename X::reference ) , ( (MoveConstructible) postincrement_result ) , ( requires HasDereference<postincrement_result> ) , ( (reference)(operator dereference)( (X&) ) ) , ( (reference)(operator dereference)( (X&&) ) ) , ( (X&)(operator preincrement)( (X&) ) ) , ( (postincrement_result)(operator postincrement)( (X&), (int) ) ) )

Page 87: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 87/98

Everybody's favorite concepts... Iterators (N2914)!!!

concept Iterator<typename X> : Semiregular<X> { MoveConstructible reference = typename X::reference; MoveConstructible postincrement_result; requires HasDereference<postincrement_result>; reference operator*(X&); reference operator*(X&&); X& operator++(X&); postincrement_result operator++(X&, int); }

BOOST_GENERIC_CONCEPT ( (Iterator)( (typename) X ), ( public Semiregular<X> ) , ( (MoveConstructible) reference, typename X::reference ) , ( (MoveConstructible) postincrement_result ) , ( requires HasDereference<postincrement_result> ) , ( (reference)(operator dereference)( (X&) ) ) , ( (reference)(operator dereference)( (X&&) ) ) , ( (X&)(operator preincrement)( (X&) ) ) , ( (postincrement_result)(operator postincrement)( (X&), (int) ) ) )

Page 88: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 88/98

Everybody's favorite concepts... Iterators (N2914)!!!

concept Iterator<typename X> : Semiregular<X> { MoveConstructible reference = typename X::reference; MoveConstructible postincrement_result; requires HasDereference<postincrement_result>; reference operator*(X&); reference operator*(X&&); X& operator++(X&); postincrement_result operator++(X&, int); }

BOOST_GENERIC_CONCEPT ( (Iterator)( (typename) X ), ( public Semiregular<X> ) , ( (MoveConstructible) reference, typename X::reference ) , ( (MoveConstructible) postincrement_result ) , ( requires HasDereference<postincrement_result> ) , ( (reference)(operator dereference)( (X&) ) ) , ( (reference)(operator dereference)( (X&&) ) ) , ( (X&)(operator preincrement)( (X&) ) ) , ( (postincrement_result)(operator postincrement)( (X&), (int) ) ) )

Page 89: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 89/98

Skip ahead to RandomAccessIterators... concept RandomAccessIterator<typename X> : BidirectionalIterator<X>, LessThanComparable<X> { MoveConstructible subscript_reference; requires Convertible<subscript_reference, const value_type&>; X& operator+=(X&, difference_type); X operator+ (const X& x, difference_type n) { X tmp(x); tmp += n; return tmp; } X operator+ (difference_type n, const X& x) { X tmp(x); tmp += n; return tmp; } X& operator-=(X&, difference_type); X operator- (const X& x, difference_type n) { X tmp(x); tmp -= n; return tmp; } difference_type operator-(const X&, const X&); subscript_reference operator[](const X& x, difference_type n); }

I hope you like parentheses.

Page 90: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 90/98

Skip ahead to RandomAccessIterators... concept RandomAccessIterator<typename X> : BidirectionalIterator<X>, LessThanComparable<X> { MoveConstructible subscript_reference; requires Convertible<subscript_reference, const value_type&>; X& operator+=(X&, difference_type); X operator+ (const X& x, difference_type n) { X tmp(x); tmp += n; return tmp; } X operator+ (difference_type n, const X& x) { X tmp(x); tmp += n; return tmp; } X& operator-=(X&, difference_type); X operator- (const X& x, difference_type n) { X tmp(x); tmp -= n; return tmp; } difference_type operator-(const X&, const X&); subscript_reference operator[](const X& x, difference_type n); }

BOOST_GENERIC_CONCEPT ( (RandomAccessIterator)( (typename) X ), ( public BidirectionalIterator<X>, LessThanComparable<X> ) , ( (MoveConstructible) subscript_reference ) , ( requires Convertible<subscript_reference, const typename BidirectionalIterator<X>::value_type&> ) , ( (X&)(operator plus_assign)( (X&), (typename BidirectionalIterator<X>::difference_type ) ) ) , ( (X)(operator plus)( (const X&) x, (typename BidirectionalIterator<X>::difference_type) n ) ) , ( (X)(operator plus)( (typename BidirectionalIterator<X>::difference_type) n, (const X&) x ) ) , ( (X&)(operator minus_assign)( (X&), (typename BidirectionalIterator<X>::difference_type) ) ) , ( (X)(operator minus)( (const X&) x, (typename BidirectionalIterator<X>::difference_type) n ) ) , ( (difference_type)(operator minus)( (const X&), (const X&) ) ) , ( (subscript_reference)(operator subscript)( (const X&), (typename BidirectionalIterator<X>::difference_type) ) ) )

Page 91: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 91/98

Skip ahead to RandomAccessIterators... concept RandomAccessIterator<typename X> : BidirectionalIterator<X>, LessThanComparable<X> { MoveConstructible subscript_reference; requires Convertible<subscript_reference, const value_type&>; X& operator+=(X&, difference_type); X operator+ (const X& x, difference_type n) { X tmp(x); tmp += n; return tmp; } X operator+ (difference_type n, const X& x) { X tmp(x); tmp += n; return tmp; } X& operator-=(X&, difference_type); X operator- (const X& x, difference_type n) { X tmp(x); tmp -= n; return tmp; } difference_type operator-(const X&, const X&); subscript_reference operator[](const X& x, difference_type n); }

BOOST_GENERIC_CONCEPT ( (RandomAccessIterator)( (typename) X ), ( public BidirectionalIterator<X>, LessThanComparable<X> ) , ( (MoveConstructible) subscript_reference ) , ( requires Convertible<subscript_reference, const typename BidirectionalIterator<X>::value_type&> ) , ( (X&)(operator plus_assign)( (X&), (typename BidirectionalIterator<X>::difference_type ) ) ) , ( (X)(operator plus)( (const X&) x, (typename BidirectionalIterator<X>::difference_type) n ) ) , ( (X)(operator plus)( (typename BidirectionalIterator<X>::difference_type) n, (const X&) x ) ) , ( (X&)(operator minus_assign)( (X&), (typename BidirectionalIterator<X>::difference_type) ) ) , ( (X)(operator minus)( (const X&) x, (typename BidirectionalIterator<X>::difference_type) n ) ) , ( (difference_type)(operator minus)( (const X&), (const X&) ) ) , ( (subscript_reference)(operator subscript)( (const X&), (typename BidirectionalIterator<X>::difference_type) ) ) )

Page 92: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concepts

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 92/98

Skip ahead to RandomAccessIterators... concept RandomAccessIterator<typename X> : BidirectionalIterator<X>, LessThanComparable<X> { MoveConstructible subscript_reference; requires Convertible<subscript_reference, const value_type&>; X& operator+=(X&, difference_type); X operator+ (const X& x, difference_type n) { X tmp(x); tmp += n; return tmp; } X operator+ (difference_type n, const X& x) { X tmp(x); tmp += n; return tmp; } X& operator-=(X&, difference_type); X operator- (const X& x, difference_type n) { X tmp(x); tmp -= n; return tmp; } difference_type operator-(const X&, const X&); subscript_reference operator[](const X& x, difference_type n); }

BOOST_GENERIC_CONCEPT ( (RandomAccessIterator)( (typename) X ), ( public BidirectionalIterator<X>, LessThanComparable<X> ) , ( (MoveConstructible) subscript_reference ) , ( requires Convertible<subscript_reference, const typename BidirectionalIterator<X>::value_type&> ) , ( (X&)(operator plus_assign)( (X&), (typename BidirectionalIterator<X>::difference_type ) ) ) , ( (X)(operator plus)( (const X&) x, (typename BidirectionalIterator<X>::difference_type) n ) ) , ( (X)(operator plus)( (typename BidirectionalIterator<X>::difference_type) n, (const X&) x ) ) , ( (X&)(operator minus_assign)( (X&), (typename BidirectionalIterator<X>::difference_type) ) ) , ( (X)(operator minus)( (const X&) x, (typename BidirectionalIterator<X>::difference_type) n ) ) , ( (difference_type)(operator minus)( (const X&), (const X&) ) ) , ( (subscript_reference)(operator subscript)( (const X&), (typename BidirectionalIterator<X>::difference_type) ) ) )

Page 93: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concept Maps

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 93/98

The Hard Part Is Over

Page 94: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concept Maps

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 94/98

Pointers as RandomAccessIterators

template<ObjectType T> concept_map RandomAccessIterator<T*> { typedef T value_type; typedef ptrdiff_t difference_type; typedef T& reference; typedef T* pointer; }

Page 95: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concept Maps

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 95/98

Pointers as RandomAccessIterators

template<ObjectType T> concept_map RandomAccessIterator<T*> { typedef T value_type; typedef ptrdiff_t difference_type; typedef T& reference; typedef T* pointer; }

BOOST_GENERIC_CONCEPT_MAP ( ( template ( (class) T ) ), (RandomAccessIterator)(T*) , ( typedef T value_type ) , ( typedef ptrdiff_t difference_type ) , ( typedef T& reference ) , ( typedef T* pointer ) )

Page 96: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Creating Concept Maps

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 96/98

Pointers as RandomAccessIterators

template<ObjectType T> concept_map RandomAccessIterator<T*> { typedef T value_type; typedef ptrdiff_t difference_type; typedef T& reference; typedef T* pointer; }

BOOST_GENERIC_CONCEPT_MAP ( ( template ( (class) T ) ), (RandomAccessIterator)(T*) , ( typedef T value_type ) , ( typedef ptrdiff_t difference_type ) , ( typedef T& reference ) , ( typedef T* pointer ) )

Page 97: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Future Direction

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 97/98

Automatically Generate Archetypes

Improve Preprocessor Error Detection

Create Quickbook Documentation

Start Testing on Clang

Add Type-Template Requirements

Parse Variadic Concepts

Allow Ref-Qualifiers on Member-Function Requirements

Finish Implementing the Concepts of N2914

Do Basic Syntax Checking on Axioms

Optimize Preprocessing

Make a Backend Targeting ConceptGCC and ConceptClang

Get Boost.Generic Reviewed and [Hopefully] into Boost

Create Concepts for BGL, Boost.GIL and other Boost Libraries

Automatic Creation of Type Erasure Constructs (I.e. Boost.Any, Boost.Function)

Page 98: Boost.Generic: Concepts without Conceptsraw.githubusercontent.com/boostcon/2011...The Necessary Tools Boost.Generic: Concepts without Concepts 26/98 © 2011 Matt Calabrese C++ 0x Syntax

Questions

© 2011 Matt Calabrese Boost.Generic: Concepts without Concepts 98/98


Recommended