Class Introspection in C++
Download
Report
Transcript Class Introspection 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, Hungary
{scamel, gsd}@elte.hu
GPCE'04, Vancouver
1
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
GPCE'04, Vancouver
2
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
GPCE'04, Vancouver
3
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
GPCE'04, Vancouver
4
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)
GPCE'04, Vancouver
5
Compile-time Adaptation
A program can observe its state
May make decisions depending on state
Template metaprogramming, e.g. boost::mpl
E.g. a container decide to store:
Data structures
Implementation strategies
Comparable values in binary tree
Other values in list
Compiler rules apply for generated program
GPCE'04, Vancouver
6
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
GPCE'04, Vancouver
7
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
GPCE'04, Vancouver
8
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, “<=“);
GPCE'04, Vancouver
9
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
GPCE'04, Vancouver
10
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_traits for concept checking
GPCE'04, Vancouver
11
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)
GPCE'04, Vancouver
12
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]; };
GPCE'04, Vancouver
13
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) );
GPCE'04, Vancouver
14
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> {};
GPCE'04, Vancouver
15
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()) );
GPCE'04, Vancouver
16
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)
GPCE'04, Vancouver
17
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)
);
GPCE'04, Vancouver
18
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)
);
GPCE'04, Vancouver
19
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;
GPCE'04, Vancouver
20
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 )
);
GPCE'04, Vancouver
21
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< )
};
};
GPCE'04, Vancouver
22
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
GPCE'04, Vancouver
23
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?
GPCE'04, Vancouver
24
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
GPCE'04, Vancouver
25
Further Plans
Implement more elementary conditions
Check theorethical limitation of
implementation
Implement a concept-checking library
usable in the STL
GPCE'04, Vancouver
26
Thank You!
See related material at
http://gsd.web.elte.hu
GPCE'04, Vancouver
27