1 / 27

Towards a General Template Introspection Library in C++

Towards a General Template Introspection Library in C++. István Z ólyomi , Zolt án Porkoláb Department of Programming Languages and Compilers Eötvös Loránd University, Budapest, Hungar y {scamel, gsd}@elte.hu. C++ Templates. Provides language support for parametric polymorphism

jaguar
Download Presentation

Towards a General Template Introspection Library in C++

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

E N D

Presentation Transcript


  1. Towards a General Template Introspection Library in C++ István Zólyomi, Zoltán Porkoláb Department of Programming Languages and Compilers Eötvös Loránd University, Budapest, Hungary {scamel, gsd}@elte.hu

  2. C++ Templates • Provides language support for parametric polymorphism • “Type-aware smart macros” • Many checks are delayed until instantiation • No restrictions on parameters • Templates alone form a Turing-complete functional language inside C++ • Based on template specializations

  3. Issues on Templates • Lazy evaluation: instantiate template members only on request • Wider scale of parameters supported • Avoid code bloat • Unexpected late errors • Hard to decode error messages • Classic example: • Member function of a class template using srot() instead of sort() compiles • Compile error when calling member function

  4. Introspection • Entity can observe its own state • Information gained in runtime from: • Interpreter (Perl, Ruby, etc) • VM (Java, .Net, etc) • Environment (C++ RTTI) • Information gained from compiler • Direct language support • Hand written exploits

  5. Introspection in C++ • Limited direct support in the language • sizeof • Would be useful to • Make restrictions on template parameters (concept checking) • Extend current type system (generate conversions, operations) • Optimization (e.g. expression templates)

  6. Compile-time Adaptation • A program can observe its state • May make decisions depending on state • Data structures • Implementation strategies • Template metaprogramming, e.g. boost::mpl • E.g. a container decide to store: • Comparable values in binary tree • Other values in list • Compiler rules apply for generated program

  7. Concept Checking • Concept: list of requirements on a type • Enforce concepts on template parameters immediately at instantiation • Improve implementation quality • Especially useful at the STL, e.g. for iterator categories

  8. Concept Checking in Other Languages • Parameter type must implement interface or derive from base class • Java interface Sortable { ... } class SortedList <T extends Sortable> ... • Eiffel class SORTED_LIST [T -> COMPARABLE] ... • Similar in functional languages

  9. Concept Checking in Other Languages • Ada: generic interface, no inheritance required generic --- Element type type T is private; --- Comparision on element type with function “<“ (X,Y: T) return boolean is <>; package Sorted_List ... end --- Generics are instantiated explicitly package SL is new Sorted_List(MyType, “<=“);

  10. Concept Checking Techniques • Currently used in C++: • require (GNU STL) • boost::concept_check • Shortages • No elementary conditions identified • No orthogonality • No composition: • “Fulfill or die” philosophy • Implicit conjunction • No cooperation with other libraries

  11. Ideal Concept Checking Library • Compile time “execution” • Identifying elementary conditions • Orthogonal design • Boolean results instead of aborting compilation • Condition composition • Cooperation with metaprogramming libraries • Something like an extension to boost::type_traitsfor concept checking

  12. Goals • Implement introspection library to enable concept checking that is close to ideal • Cooperation with metaprogramming libraries (e.g. boost::mpl) • Use only standard C++ • No language extension • No typeof operator • No compiler-specific features • No external tools (e.g. gcc-xml)

  13. Programming Techniques • Ellipse: accept any parameter void f(...); • Function overload Yes isOk(ExpectedType); // expected case No isOk(...); // rescue case • Return types have different sizes struct No { char dummy; }; struct Yes { char dummy[2]; };

  14. Programming Techniques • Map return types to boolean values sizeof( isOk(expression) ) == sizeof(Yes); • Convenience macro for mapping // --- The same with macro shortcut bool res = CONFORMS( isOk(expression) );

  15. Programming Techniques • boost::enable_if // --- Enabled case template <bool b, class T> struct enable_if { typedef T Result; }; // --- Specialized disabled case template <class T> struct enable_if<false> {};

  16. Programming Techniques • SFINAE rule(Substitution failure is not an error) // --- Expected case for T enable_if<sizeof(T::Feature), Yes> f(T&); // --- Rescue case No f(...); bool res = CONFORMS( f(Type()) );

  17. Elementary Conditions • Checks implemented for • Existence of embedded type with name • Existence of class member with name • Exact type of embedded type • Exact type of member (both function and data)

  18. Embedded Type Name • Inspect if type has an embedded type with given name • Need macros PREPARE_TYPE_CHECKER(iterator); ... // --- Look for name ‘iterator’ in T const bool res = CONFORMS( TYPE_IN_CLASS(iterator, T) );

  19. Member Name • Inspect if type has a non-type member (either data or function) with given name • Similar to previous condition PREPARE_MEMBER_CHECKER(size); ... // --- Look for member ‘size’ in T const bool res = CONFORMS( MEMBER_IN_CLASS(size, T) );

  20. Nested Type • Inspect nested type if name exists • Cooperate with other tools, e.g. boost::type_traits // --- Inspect traits of nested type const bool isScalar = type_traits<T::value_type>::is_scalar; // --- Inspect exact type const bool isInteger = SameTypes<int, T::value_type>::Result;

  21. Members • Exact type of member if name exists // --- Inspect if ‘size’ is data member const bool isDataMember = CONFORMS( Member<unsigned int>::NonStatic( &T::size ) ); // --- Inspect if ‘size’ is member function typedef unsigned int Fun() const; const bool isMemberFunction = CONFORMS( Member<Fun>::NonStatic( &T::size ) );

  22. Composite Conditions • User can easily assemble complex conditions template <class T> struct LessThanComparable { enum { Conforms = CONFORMS( Function<bool (const T&, const T&)>:: Static( &::operator< ) || CONFORMS( Function<bool (const T&) const>:: NonStatic( &T::operator< ) }; };

  23. Hacking? • Two opinions: • Should be language extension • Should be user code • Language change • Major issue • Must have proved design • Should be based on previous experiences

  24. Open Questions • What is the minimal orthogonal set of conditions? • What other conditions are expected to be implemented? • What conditions are theoretically impossible to implement with current language standard? • DefaultConstructable?

  25. Summary • Separation of introspection from intercession • Implemented elementary conditions • Observation provides compile time bool • Easy to define new user conditions • Arbitrary combination of conditions is possible • And, or, negate • Specialization on this result is possible • Supports compile-time adaptation • Supports concept checking

  26. Further Plans • Implement more elementary conditions • Check theorethical limitation of implementation • Implement a concept-checking library usable in the STL

  27. Thank You! See related material at http://gsd.web.elte.hu

More Related