SlideShare ist ein Scribd-Unternehmen logo
1 von 61
ACCU 2007
Generative Programming in the Large
Applied meta-programming
Schalk W. Cronjé
ysb33r@gmail.com
ACCU 2007
Even in this new millennium, many engineers will still
build components that have very little reuse potential
due to the inflexible way that they were constructed.
This leads to excessive time required to adapt a
component for usage in another system.
ACCU 2007
The world of modern
C++ Generative Programming
is a vastly untapped field
(we are just scraping the surface)
ACCU 2007
Definition
It is a software engineering paradigm where the aim is
to automatically manufacture highly customised and
optimised intermediate or end-products from
elementary, reusable components by means of
configuration knowledge.
Implies Code Generation
Domain-specific language
Generic Techniques
ACCU 2007
Elements of Generative
Programming
Problem space Solution space
Configuration
Knowledge
Illegal feature
combinations
Default settings &
dependencies
Construction rules
Optimisations
Configured ComponentsDomain-specific
concepts
Features
Generic Components
ACCU 2007
Key Code-level Strategy
ACCU 2007
For effective implementation there is one basic principle
that encompasses most GP strategies:
Dijkstra's Separation of Concerns
This principle accepts the fact that we cannot deal with
many issues at once and that important issues should
be addressed with purpose.
ACCU 2007
Key Code-level Strategies
Develop elementary components as generic
components
Fully testable outside of the intended product
configuration
Configure these components using generated artefacts
appropriate to the programming language
Aim for zero cyclomatic-complexity in the generated
artefacts
Eliminate defects as early as possible
ACCU 2007
In the large ...
Generative C++ can lead to large number of
configuration classes or meta-classes being
generated.
It is not uncommon to work with 50+ tag classes within
a single type-list
Effective integration of meta-programming, compile-
time paradigms and run-time paradigms are required.
Code-bloat must be avoided!
ACCU 2007
Conventions
For the examples assume that the following
namespace aliases exist
using namespace AccuConf;
namespace mpl = AccuConf::mpl;
namespace bmpl = boost::mpl;
All code are implemented in namespace
AccuConf.
ACCU 2007
Building a rule evaluator
(as an example of a generative library)
ACCU 2007
Requirement #1:
Solve complex boolean statements
if (cond_A && cond_B || !cond_C)
return outcome_A;
else if (cond_D)
return outcome_B;
else
return outcome_C;
ACCU 2007
Requirement #2:
Rule-types are defined in a DSL
condition_expr:
input: IP-address
operation: ==
condition_expr:
input: IP-address
operation: in_netmask
condition_expr:
input: Email-address
operation: regex_match
ACCU 2007
Requirement #3:
Short-circuit
// Jump to evaluate !cond_C
if (cond_A && !cond_A || !cond_C)
// Never evaluate cond_D
if( cond_B || !cond_B || cond_D)
// Don't evalute cond_A twice
if( cond_A || cond_A )
if( cond_A && cond_A )
ACCU 2007
Requirement #4:
Compile-time & run-time rules
// Hard-code compile-time
rule1 = cond_A && cond_B
// Loaded at run-time
rule2 = load_rule( "ip in FEFE::/64" );
ACCU 2007
Requirement #5:
Early enforcment
Only allow attribute-operator combinations that have
been defined in DSL
Only allow attributes to be passed that were defined in
DSL
ACCU 2007
The conceptual evaluator
Evaluating rules
class Evaluator
{
public:
/**Evaluates the rules against a supplied set
* of attributes
* @param A A collected set of attributes that
will
* be used as input to the rules.
* @return The outcome associated with the rule
* that triggered
*/
Outcome const&
resolve( Properties const& A) const;
};
ACCU 2007
The conceptual evaluator
Adding rules
class Evaluator
{
public:
Outcome const&
resolve( Properties const& A) const;
/**Adds a rule to the rule set
* @param O The outcome to return if this rule
* triggers
* @param N The order of this rule in the ruleset
* @param R the rule to add
*/
void add_rule(
Outcome const& O,Order const& N,Rule const& R
);
};
ACCU 2007
Idiom #1: Generative Property Bag
What does the Properties class look like?
ACCU 2007
Properties class
This can be implemented as a heap-based or a stack-
based approach.
Heap-based:
More memory-efficient, only allocate stored
attributes. Suffers heap-access penalty. Potential
for heap fragmentation.
Stack-based:
Pre-allocate space for all attributes, even if not used.
ACCU 2007
Heap-based Properties class
Use boost::any to provide generic storage
Use boost::map to provide conditional storage
Index using meta-indexes
template <typename GeneratedPropSet>
class Properties
{
public:
// To be implemented ...
private:
typedef std::map< int,boost::any > container_type;
container_type m_attrs;
};
ACCU 2007
Generated Property Set
struct prop
{
struct ip_addr
{
typedef IPAddress value_type;
typedef to-be-decided valid_matches;
};
struct email_addr
{
typedef std::string value_type;
typedef to-be-decided valid_matches;
};
typedef boost::mpl::vector< ip_addr, email_addr >
valid_attrs;
};
ACCU 2007
Setting a Property
template <typename GeneratedPropSet>
class Properties
{
public:
template <typename P>
void set(
typename mpl::property_value<P>::type const&
);
private:
typedef std::map< int,boost::any > container_type;
};
Properties<prop> A;
A.set< prop::ip_addr >( "192.168.1.1" );
ACCU 2007
Implementing Property::set
template <typename GeneratedPropSet>
template <typename P>
void Properties<GeneratedPropSet>::set(
typename mpl::property_value<P>::type const& v_
)
{
// Ensure that P is valid !
BOOST_MPL_ASSERT_MSG(
(bmpl::contains<
typename mpl::valid_properties<
GeneratedPropSet >::type,P
>::value),
THIS_IS_NOT_A_VALID_PROPERTY,
(P)
);
// Rest to follow ...
}
Static Assertion provides
relatively useful compile-time
error if a invalid type is supplied
ACCU 2007
Implementing Property::set
template <typename GeneratedPropSet>
template <typename P>
void Properties<GeneratedPropSet>::set(
typename mpl::property_value<P>::type const& v_
)
{
// Ensure that P is valid !
BOOST_MPL_ASSERT_MSG(
bmpl::contains<
typename mpl::valid_properties<
GeneratedPropSet >::type,P
>::value,
THIS_IS_NOT_A_VALID_PROPERTY,
(P)
);
// Rest to follow ...
}
boost::mpl::contains is a
metapredicate that returns TRUE
if P is in the list of valid
properties
ACCU 2007
Implementing Property::set
template <typename GeneratedPropSet>
template <typename P>
void Properties<GeneratedPropSet>::set(
typename mpl::property_value<P>::type const& v_
)
{
// Ensure that P is valid !
BOOST_MPL_ASSERT_MSG(
(bmpl::contains<
typename mpl::valid_properties<
GeneratedPropSet >::type,P
>::value),
THIS_IS_NOT_A_VALID_PROPERTY,
(P)
);
// Rest to follow ...
}
mpl::valid_properties is our own
metaclass to extract the MPL
sequence of valid property names
from GeneratedPropSet
ACCU 2007
Implementing Property::set
template <typename GeneratedPropSet>
template <typename P>
void Properties<GeneratedPropSet>::set(
typename mpl::property_value<P>::type const& v_
)
{
BOOST_MPL_ASSERT_MSG( ... );
// Find key for map
const int pos =
mpl::property_pos< GeneratedPropSet, P >::value
;
// Rest to follow ...
}
mpl::property_pos is our own metaclass
returning the relative position of a type
in a typelist. We use this value as a key
into the map. Due to the MPL_ASSERT
we can be ensured that this is a
valid value.
ACCU 2007
Implementing Property::set
template <typename GeneratedPropSet>
template <typename P>
void Properties<GeneratedPropSet>::set(
typename mpl::property_value<P>::type const& v_
)
{
BOOST_MPL_ASSERT_MSG( ... );
// Find key for map
const int pos =
mpl::property_pos< GeneratedPropSet, P >::value
;
// Rest to follow ...
}
Use of 'const int' allows for optimisation
at compile-time
ACCU 2007
Implementing Property::set
template <typename GeneratedPropSet>
template <typename P>
void Properties<GeneratedPropSet>::set(
typename mpl::property_value<P>::type const& v_
)
{
BOOST_MPL_ASSERT_MSG( ... );
const int pos = ... ;
// Assign the value
typedef typename mpl::property_value<P>::type
value_type;
m_attrs[pos] = v_;
}
ACCU 2007
Implementing Property::set
(alternative)
template <typename GeneratedPropSet>
template <typename P,typename V>
void Properties<GeneratedPropSet>::set(
V const& v_
)
{
BOOST_MPL_ASSERT_MSG( ... );
const int pos = ... ;
// Assign the value
typedef typename mpl::property_value<P>::type
value_type;
m_attrs[pos] = value_type(v_);
}
ACCU 2007
Getting a Property
template <typename GeneratedPropSet>
class Properties
{
public:
template <typename P>
typename mpl::property_value<P>::type const&
get() const;
private:
typedef std::map< int,boost::any > container_type;
};
Properties<prop> A;
A.set< prop::ip_addr >( "192.168.1.1" );
std::cout << A.get< prop::ip_addr >( );
ACCU 2007
Implementing Property::get
template <typename GeneratedPropSet>
template <typename P>
typename mpl::property_value<P>::type const&
Properties<GeneratedPropSet>::get() const
{
BOOST_MPL_ASSERT_MSG( ... );
// Find key for map
typename container_type::const_iterator itr =
m_attrs.find(
mpl::property_pos< GeneratedPropSet, P
>::value
);
// Rest to follow ...
}
Reusing mpl::property_pos we obtain
an iterator to the appropiate property.
Note the use of MPL_ASSERT to ensure
a valid index value
ACCU 2007
Implementing Property::get
template <typename GeneratedPropSet>
template <typename P>
typename mpl::property_value<P>::type const&
Properties<GeneratedPropSet>::get() const
{
BOOST_MPL_ASSERT_MSG( ... );
... itr = m_attrs.find( ... );
if( m_attrs.end() == itr )
throw range_error("Property not set");
// Rest to follow ...
}
Throw an exception if the property is not
set. Use Property::is_set predicate if a
no_throw check is needed.
(is_set implementation left as an exercise)
ACCU 2007
Implementing Property::get
template <typename GeneratedPropSet>
template <typename P>
typename mpl::property_value<P>::type const&
Properties<GeneratedPropSet>::get() const
{
BOOST_MPL_ASSERT_MSG( ... );
... itr = m_attrs.find( ... );
if( m_attrs.end() == itr ) ... ;
typedef typename mpl::property_value<P>::type
value_type;
return *boost::any_cast<value_type>
(&(itr->second));
}
We can assume that
the type stored is
correct. Need to use
the & to invoke a
non-copy version
of any_cast.
ACCU 2007
Idiom #2: GGS
Generic-Generated Separation: Access to
generated typelists from generic code should
go through metaclasses.
ACCU 2007
MPL metaclasses
Abstract access to type information through
metaclasses
This allows for specialisation when needed
Improves long-term maintenance
ACCU 2007
Obtaining the value_type
template <typename Property>
struct property_value
{
typedef typename Property::value_type type;
};
ACCU 2007
Sequence of Valid Properties
template <typename Properties>
struct valid_properties
{
typedef typename Properties::valid_properties
type;
};
ACCU 2007
Property Position
template <typename Properties,typename Property>
struct valid_properties :
bmpl::find<
typename valid_properties< Properties>::type,
Property
>::type::pos
{
// Prevent invalid Property
BOOST_MPL_ASSERT_MSG(
bmpl::contains<
typename valid_properties<
Properties>::type,
Property
>::value,
PROPERTY_NOT_FOUND_IN_SEQUENCE,
(Property,Properties)
);
};
ACCU 2007
Idiom #3: Visit Each
Apply an operation to each generated
member
ACCU 2007
Using Boost for_each
bmpl::for_each<
mpl::valid_properties<Properties>::type
>( FUNCTOR() );
struct FUNCTOR
{
template <typename P>
void operator()(P) const;
};
For each type in
sequence calls the
functor
ACCU 2007
Using Boost for_each
bmpl::for_each<
mpl::valid_properties<Properties>::type
>( FUNCTOR() );
struct FUNCTOR
{
template <typename P>
void operator()(P) const;
};
Functor must be able
to accommodate each
type, otherwise
compile-error will occur
ACCU 2007
Using Boost for_each
struct print_ip
{
Properties const& p;
print_ip(Properties const& p_)
: p(p_) {}
template <typename P>
void operator()(P) const
{}
void operator()(ip_addr) const
{std::cout << p.get<ip_addr>();}
};
bmpl::for_each<
mpl::valid_properties<Properties>::type
>( print_ip(my_properties) );
ACCU 2007
Idiom #4: Type-erasure
A known interface irrespective of the types
used
ACCU 2007
Rule Evaluation Signature
template <typename Properties>
bool Functor( Properties const& );
boost::function< bool(Properties const&) >
ACCU 2007
Rule Class
template <typename Properties>
class Rule
{
public:
// C-tors to follow ...
Rule operator || (Rule const&) const;
Rule operator && (Rule const&) const;
Rule operator !() const;
bool operator()(Properties const&) const;
private:
boost::function< bool(Properties const&) > m_rule;
};
ACCU 2007
Rule Class
template <typename Properties>
class Rule
{
public:
template <
typename Property,
typename Operand
>
Rule( Operand<Property> const& op_ );
};
ACCU 2007
Idiom #5: Hekaton Typelist
Working around limitations in existing typelist
libraries
ACCU 2007
Limitations in Boost MPL
sequences
Maximum size of template parameter list is
implementation-dependant
Typically 20
GP might require very long lists
100 types are not uncommon
A special type-list might be needed to convert a
very long generated list into a standard Boost
MPL sequence.
ACCU 2007
Hekaton-typelist
template <
typename T0 = bmpl::na,
typename T1 = bmpl::na,
...,
typename T99 = bmpl::na
>
struct typelist
{
typedef bmpl::vector<T0,...,T19> _list0;
typedef bmpl::vector<T20,...,T39> _list1;
typedef bmpl::vector<T40,...,T59> _list2;
// etc.
// Join lists
typedef bmpl::joint_view<_list0,_list1 > _join0;
typedef bmpl::joint_view<_join0,_list2 > _join1;
//etc.
// until the last join which becomes
typedef to-be-defined type;
};
ACCU 2007
Hekaton-typelist (detail)
namespace detail
{
template <
typename V0 = bmpl::vector<>,
typename V1 = bmpl::vector<>,
...,
typename V9 = bmpl::vector<>
>
struct typelist
{
// detail to follow ...
};
} // namespace detail
ACCU 2007
Hekaton-typelist (detail)
namespace detail
{
#define P_LIST(z,n,t) BOOST_PP_COMMA_IF(n) 
typename V##n = t
template < BOOST_PP_REPEAT(10,P_LIST,bmpl::vector<>) >
struct typelist
{
// detail to follow ...
};
#undef P_LIST
} // namespace detail
ACCU 2007
Hekaton-typelist (detail)
namespace detail
{
#define P_LIST(z,n,t) BOOST_PP_COMMA_IF(n) 
typename V##n = t
template < BOOST_PP_REPEAT(10,P_LIST,bmpl::vector<>)
>
struct typelist
{
typedef bmpl::joint_view<_V0,_V1 > _join0;
typedef bmpl::joint_view<_join0,V2 > _join1;
//etc. until the last join which becomes
typedef bmpl::joint_view<_join8,V9 > type;
};
#undef P_LIST
} // namespace detail
ACCU 2007
Hekaton-typelist (final)
#define P_LIST1(z,n,t) BOOST_PP_COMMA_IF(n) 
typename T##n = t
#define P_LIST2(z,n,t) BOOST_PP_COMMA_IF(n) t##n
#define P_LIST3(z,n,t) BOOST_PP_COMMA_IF(n) 
t < BOOST_PP_REPEAT_FROM_TO( 
BOOST_PP_MUL(n,20), 
BOOST_PP_ADD(BOOST_PP_MUL(n,20),20), 
P_LIST2,T ) 
>
template < BOOST_PP_REPEAT( 100,P_LIST1,bmpl::na ) >
struct typelist : detail::typelist<
BOOST_PP_REPEAT( 5,P_LIST3, bmpl::vector )
> ::type
{};
#undef P_LIST1
#undef P_LIST2
#undef P_LIST3
ACCU 2007
Idiom #6: Discriminant Union from
Typelist
boost::make_variant_over
ACCU 2007
Discriminant Union
typedef mpl::valid_properties<prop>::type
example_typelist;
typedef boost::make_variant_over<
example_typelist
>::type example_variant;
X
ACCU 2007
Discriminant Union
struct extract_value_type
{
template <typename T> : mpl::property_value<T>
struct apply
{};
};
typedef boost::transform_view<
mpl::valid_properties<prop>::type,
extract_value_type
>::type example_typelist
typedef boost::make_variant_over<
example_typelist
>::type example_variant;
ACCU 2007
Implementation Specifics
ACCU 2007
Compiler Limitations
Few compilers can handle the deep level of
template instantiation very well
gcc 4.x is fast
VC 8 (VS2005) is adequate
gcc 3.x is slow and has big memory footprint
It is not always possible to use the puristic
template solution
Use the Boost Preprocessor Library
Generate code of higher levels of cyclomatic-
complexity
ACCU 2007
Further Reading
ACCU 2007
Touching the void
Pushing C++ skills far beyond the knowledge of
many C++ practitioners
Politics of introducing a new technology
Teaches very good software skills outside the
C++ domain
Am I in the wrong language?
(Yeah, thanks Kevlin!)
Shows requirements for future languages
Powerful syntax
Simplicity of expression

Weitere ähnliche Inhalte

Was ist angesagt?

Async await in C++
Async await in C++Async await in C++
Async await in C++cppfrug
 
មេរៀនៈ Data Structure and Algorithm in C/C++
មេរៀនៈ Data Structure and Algorithm in C/C++មេរៀនៈ Data Structure and Algorithm in C/C++
មេរៀនៈ Data Structure and Algorithm in C/C++Ngeam Soly
 
Дмитрий Копляров , Потокобезопасные сигналы в C++
Дмитрий Копляров , Потокобезопасные сигналы в C++Дмитрий Копляров , Потокобезопасные сигналы в C++
Дмитрий Копляров , Потокобезопасные сигналы в C++Sergey Platonov
 
A Future for R: Parallel and Distributed Processing in R for Everyone
A Future for R: Parallel and Distributed Processing in R for EveryoneA Future for R: Parallel and Distributed Processing in R for Everyone
A Future for R: Parallel and Distributed Processing in R for Everyoneinside-BigData.com
 
C++ vs C#
C++ vs C#C++ vs C#
C++ vs C#sudipv
 
Uncommon Design Patterns
Uncommon Design PatternsUncommon Design Patterns
Uncommon Design PatternsStefano Fago
 
Parallel program design
Parallel program designParallel program design
Parallel program designZongYing Lyu
 
Big-data-analysis-training-in-mumbai
Big-data-analysis-training-in-mumbaiBig-data-analysis-training-in-mumbai
Big-data-analysis-training-in-mumbaiUnmesh Baile
 
Improve Vectorization Efficiency
Improve Vectorization EfficiencyImprove Vectorization Efficiency
Improve Vectorization EfficiencyIntel® Software
 
C++ Data-flow Parallelism sounds great! But how practical is it? Let’s see ho...
C++ Data-flow Parallelism sounds great! But how practical is it? Let’s see ho...C++ Data-flow Parallelism sounds great! But how practical is it? Let’s see ho...
C++ Data-flow Parallelism sounds great! But how practical is it? Let’s see ho...Jason Hearne-McGuiness
 
Optimizing Communicating Event-Loop Languages with Truffle
Optimizing Communicating Event-Loop Languages with TruffleOptimizing Communicating Event-Loop Languages with Truffle
Optimizing Communicating Event-Loop Languages with TruffleStefan Marr
 
Automated Combination of Real Time Shader Programs (EG 2007)
Automated Combination of Real Time Shader Programs (EG 2007)Automated Combination of Real Time Shader Programs (EG 2007)
Automated Combination of Real Time Shader Programs (EG 2007)Matthias Trapp
 
Building High-Performance Language Implementations With Low Effort
Building High-Performance Language Implementations With Low EffortBuilding High-Performance Language Implementations With Low Effort
Building High-Performance Language Implementations With Low EffortStefan Marr
 

Was ist angesagt? (20)

Java Semantics
Java SemanticsJava Semantics
Java Semantics
 
Async await in C++
Async await in C++Async await in C++
Async await in C++
 
Animate
AnimateAnimate
Animate
 
Builder pattern
Builder patternBuilder pattern
Builder pattern
 
GCC RTL and Machine Description
GCC RTL and Machine DescriptionGCC RTL and Machine Description
GCC RTL and Machine Description
 
C++ Coroutines
C++ CoroutinesC++ Coroutines
C++ Coroutines
 
មេរៀនៈ Data Structure and Algorithm in C/C++
មេរៀនៈ Data Structure and Algorithm in C/C++មេរៀនៈ Data Structure and Algorithm in C/C++
មេរៀនៈ Data Structure and Algorithm in C/C++
 
Дмитрий Копляров , Потокобезопасные сигналы в C++
Дмитрий Копляров , Потокобезопасные сигналы в C++Дмитрий Копляров , Потокобезопасные сигналы в C++
Дмитрий Копляров , Потокобезопасные сигналы в C++
 
Syntutic
SyntuticSyntutic
Syntutic
 
A Future for R: Parallel and Distributed Processing in R for Everyone
A Future for R: Parallel and Distributed Processing in R for EveryoneA Future for R: Parallel and Distributed Processing in R for Everyone
A Future for R: Parallel and Distributed Processing in R for Everyone
 
C++ vs C#
C++ vs C#C++ vs C#
C++ vs C#
 
Uncommon Design Patterns
Uncommon Design PatternsUncommon Design Patterns
Uncommon Design Patterns
 
Parallel program design
Parallel program designParallel program design
Parallel program design
 
Big-data-analysis-training-in-mumbai
Big-data-analysis-training-in-mumbaiBig-data-analysis-training-in-mumbai
Big-data-analysis-training-in-mumbai
 
Klee introduction
Klee  introductionKlee  introduction
Klee introduction
 
Improve Vectorization Efficiency
Improve Vectorization EfficiencyImprove Vectorization Efficiency
Improve Vectorization Efficiency
 
C++ Data-flow Parallelism sounds great! But how practical is it? Let’s see ho...
C++ Data-flow Parallelism sounds great! But how practical is it? Let’s see ho...C++ Data-flow Parallelism sounds great! But how practical is it? Let’s see ho...
C++ Data-flow Parallelism sounds great! But how practical is it? Let’s see ho...
 
Optimizing Communicating Event-Loop Languages with Truffle
Optimizing Communicating Event-Loop Languages with TruffleOptimizing Communicating Event-Loop Languages with Truffle
Optimizing Communicating Event-Loop Languages with Truffle
 
Automated Combination of Real Time Shader Programs (EG 2007)
Automated Combination of Real Time Shader Programs (EG 2007)Automated Combination of Real Time Shader Programs (EG 2007)
Automated Combination of Real Time Shader Programs (EG 2007)
 
Building High-Performance Language Implementations With Low Effort
Building High-Performance Language Implementations With Low EffortBuilding High-Performance Language Implementations With Low Effort
Building High-Performance Language Implementations With Low Effort
 

Andere mochten auch

Practical Meta Programming
Practical Meta ProgrammingPractical Meta Programming
Practical Meta ProgrammingReggie Meisler
 
A Generative Programming Approach to Developing Pervasive Computing Systems
A Generative Programming Approach to Developing Pervasive Computing SystemsA Generative Programming Approach to Developing Pervasive Computing Systems
A Generative Programming Approach to Developing Pervasive Computing SystemsDamien Cassou
 
Seeking Enligtenment - A journey of purpose rather tan instruction
Seeking Enligtenment - A journey of purpose rather tan instructionSeeking Enligtenment - A journey of purpose rather tan instruction
Seeking Enligtenment - A journey of purpose rather tan instructionSchalk Cronjé
 
Generative Software Development. Overview and Examples
Generative Software Development. Overview and ExamplesGenerative Software Development. Overview and Examples
Generative Software Development. Overview and ExamplesEelco Visser
 
Generative programming (mostly parser generation)
Generative programming (mostly parser generation)Generative programming (mostly parser generation)
Generative programming (mostly parser generation)Ralf Laemmel
 
Generative and Meta-Programming - Modern C++ Design for Parallel Computing
Generative and Meta-Programming - Modern C++ Design for Parallel ComputingGenerative and Meta-Programming - Modern C++ Design for Parallel Computing
Generative and Meta-Programming - Modern C++ Design for Parallel ComputingJoel Falcou
 
Japanese Open and Generative Design
Japanese Open and Generative DesignJapanese Open and Generative Design
Japanese Open and Generative DesignYuichi Yazaki
 
Seri Belajar Mandiri - Pemrograman C# Untuk Pemula
Seri Belajar Mandiri - Pemrograman C# Untuk PemulaSeri Belajar Mandiri - Pemrograman C# Untuk Pemula
Seri Belajar Mandiri - Pemrograman C# Untuk PemulaAgus Kurniawan
 
Probabilistic programming
Probabilistic programmingProbabilistic programming
Probabilistic programmingEli Gottlieb
 
Summary - Transformational-Generative Theory
Summary - Transformational-Generative TheorySummary - Transformational-Generative Theory
Summary - Transformational-Generative TheoryMarielis VI
 
Transformational-Generative Grammar
Transformational-Generative GrammarTransformational-Generative Grammar
Transformational-Generative GrammarRuth Ann Llego
 
Deep structure and surface structure
Deep structure and surface structureDeep structure and surface structure
Deep structure and surface structureAsif Ali Raza
 
Ubiquitous Computing
Ubiquitous ComputingUbiquitous Computing
Ubiquitous Computingu065932
 

Andere mochten auch (13)

Practical Meta Programming
Practical Meta ProgrammingPractical Meta Programming
Practical Meta Programming
 
A Generative Programming Approach to Developing Pervasive Computing Systems
A Generative Programming Approach to Developing Pervasive Computing SystemsA Generative Programming Approach to Developing Pervasive Computing Systems
A Generative Programming Approach to Developing Pervasive Computing Systems
 
Seeking Enligtenment - A journey of purpose rather tan instruction
Seeking Enligtenment - A journey of purpose rather tan instructionSeeking Enligtenment - A journey of purpose rather tan instruction
Seeking Enligtenment - A journey of purpose rather tan instruction
 
Generative Software Development. Overview and Examples
Generative Software Development. Overview and ExamplesGenerative Software Development. Overview and Examples
Generative Software Development. Overview and Examples
 
Generative programming (mostly parser generation)
Generative programming (mostly parser generation)Generative programming (mostly parser generation)
Generative programming (mostly parser generation)
 
Generative and Meta-Programming - Modern C++ Design for Parallel Computing
Generative and Meta-Programming - Modern C++ Design for Parallel ComputingGenerative and Meta-Programming - Modern C++ Design for Parallel Computing
Generative and Meta-Programming - Modern C++ Design for Parallel Computing
 
Japanese Open and Generative Design
Japanese Open and Generative DesignJapanese Open and Generative Design
Japanese Open and Generative Design
 
Seri Belajar Mandiri - Pemrograman C# Untuk Pemula
Seri Belajar Mandiri - Pemrograman C# Untuk PemulaSeri Belajar Mandiri - Pemrograman C# Untuk Pemula
Seri Belajar Mandiri - Pemrograman C# Untuk Pemula
 
Probabilistic programming
Probabilistic programmingProbabilistic programming
Probabilistic programming
 
Summary - Transformational-Generative Theory
Summary - Transformational-Generative TheorySummary - Transformational-Generative Theory
Summary - Transformational-Generative Theory
 
Transformational-Generative Grammar
Transformational-Generative GrammarTransformational-Generative Grammar
Transformational-Generative Grammar
 
Deep structure and surface structure
Deep structure and surface structureDeep structure and surface structure
Deep structure and surface structure
 
Ubiquitous Computing
Ubiquitous ComputingUbiquitous Computing
Ubiquitous Computing
 

Ähnlich wie Generative Programming In The Large - Applied C++ meta-programming

pyjamas22_ generic composite in python.pdf
pyjamas22_ generic composite in python.pdfpyjamas22_ generic composite in python.pdf
pyjamas22_ generic composite in python.pdfAsher Sterkin
 
A New Chapter of Data Processing with CDK
A New Chapter of Data Processing with CDKA New Chapter of Data Processing with CDK
A New Chapter of Data Processing with CDKShu-Jeng Hsieh
 
Distributed Computing on PostgreSQL | PGConf EU 2017 | Marco Slot
Distributed Computing on PostgreSQL | PGConf EU 2017 | Marco SlotDistributed Computing on PostgreSQL | PGConf EU 2017 | Marco Slot
Distributed Computing on PostgreSQL | PGConf EU 2017 | Marco SlotCitus Data
 
How to make a high-quality Node.js app, Nikita Galkin
How to make a high-quality Node.js app, Nikita GalkinHow to make a high-quality Node.js app, Nikita Galkin
How to make a high-quality Node.js app, Nikita GalkinSigma Software
 
Azure machine learning service
Azure machine learning serviceAzure machine learning service
Azure machine learning serviceRuth Yakubu
 
Java programming concept
Java programming conceptJava programming concept
Java programming conceptSanjay Gunjal
 
PL/CUDA - Fusion of HPC Grade Power with In-Database Analytics
PL/CUDA - Fusion of HPC Grade Power with In-Database AnalyticsPL/CUDA - Fusion of HPC Grade Power with In-Database Analytics
PL/CUDA - Fusion of HPC Grade Power with In-Database AnalyticsKohei KaiGai
 
Go Faster With Native Compilation
Go Faster With Native CompilationGo Faster With Native Compilation
Go Faster With Native CompilationPGConf APAC
 
Go faster with_native_compilation Part-2
Go faster with_native_compilation Part-2Go faster with_native_compilation Part-2
Go faster with_native_compilation Part-2Rajeev Rastogi (KRR)
 
Introduction to Chainer 11 may,2018
Introduction to Chainer 11 may,2018Introduction to Chainer 11 may,2018
Introduction to Chainer 11 may,2018Preferred Networks
 
pgconfasia2016 plcuda en
pgconfasia2016 plcuda enpgconfasia2016 plcuda en
pgconfasia2016 plcuda enKohei KaiGai
 
Moving from Jenkins 1 to 2 declarative pipeline adventures
Moving from Jenkins 1 to 2 declarative pipeline adventuresMoving from Jenkins 1 to 2 declarative pipeline adventures
Moving from Jenkins 1 to 2 declarative pipeline adventuresFrits Van Der Holst
 
Spark SQL Catalyst Code Optimization using Function Outlining with Kavana Bha...
Spark SQL Catalyst Code Optimization using Function Outlining with Kavana Bha...Spark SQL Catalyst Code Optimization using Function Outlining with Kavana Bha...
Spark SQL Catalyst Code Optimization using Function Outlining with Kavana Bha...Databricks
 
Whats new in ES2019
Whats new in ES2019Whats new in ES2019
Whats new in ES2019chayanikaa
 
Getting started with ES6
Getting started with ES6Getting started with ES6
Getting started with ES6Nitay Neeman
 

Ähnlich wie Generative Programming In The Large - Applied C++ meta-programming (20)

pyjamas22_ generic composite in python.pdf
pyjamas22_ generic composite in python.pdfpyjamas22_ generic composite in python.pdf
pyjamas22_ generic composite in python.pdf
 
Compose in Theory
Compose in TheoryCompose in Theory
Compose in Theory
 
A New Chapter of Data Processing with CDK
A New Chapter of Data Processing with CDKA New Chapter of Data Processing with CDK
A New Chapter of Data Processing with CDK
 
Oops presentation
Oops presentationOops presentation
Oops presentation
 
C++ manual Report Full
C++ manual Report FullC++ manual Report Full
C++ manual Report Full
 
Distributed Computing on PostgreSQL | PGConf EU 2017 | Marco Slot
Distributed Computing on PostgreSQL | PGConf EU 2017 | Marco SlotDistributed Computing on PostgreSQL | PGConf EU 2017 | Marco Slot
Distributed Computing on PostgreSQL | PGConf EU 2017 | Marco Slot
 
How to make a high-quality Node.js app, Nikita Galkin
How to make a high-quality Node.js app, Nikita GalkinHow to make a high-quality Node.js app, Nikita Galkin
How to make a high-quality Node.js app, Nikita Galkin
 
Azure machine learning service
Azure machine learning serviceAzure machine learning service
Azure machine learning service
 
Java programming concept
Java programming conceptJava programming concept
Java programming concept
 
PL/CUDA - Fusion of HPC Grade Power with In-Database Analytics
PL/CUDA - Fusion of HPC Grade Power with In-Database AnalyticsPL/CUDA - Fusion of HPC Grade Power with In-Database Analytics
PL/CUDA - Fusion of HPC Grade Power with In-Database Analytics
 
Balancing Power & Performance Webinar
Balancing Power & Performance WebinarBalancing Power & Performance Webinar
Balancing Power & Performance Webinar
 
Go Faster With Native Compilation
Go Faster With Native CompilationGo Faster With Native Compilation
Go Faster With Native Compilation
 
Go faster with_native_compilation Part-2
Go faster with_native_compilation Part-2Go faster with_native_compilation Part-2
Go faster with_native_compilation Part-2
 
Introduction to Chainer 11 may,2018
Introduction to Chainer 11 may,2018Introduction to Chainer 11 may,2018
Introduction to Chainer 11 may,2018
 
pgconfasia2016 plcuda en
pgconfasia2016 plcuda enpgconfasia2016 plcuda en
pgconfasia2016 plcuda en
 
Moving from Jenkins 1 to 2 declarative pipeline adventures
Moving from Jenkins 1 to 2 declarative pipeline adventuresMoving from Jenkins 1 to 2 declarative pipeline adventures
Moving from Jenkins 1 to 2 declarative pipeline adventures
 
Spark SQL Catalyst Code Optimization using Function Outlining with Kavana Bha...
Spark SQL Catalyst Code Optimization using Function Outlining with Kavana Bha...Spark SQL Catalyst Code Optimization using Function Outlining with Kavana Bha...
Spark SQL Catalyst Code Optimization using Function Outlining with Kavana Bha...
 
Qe Reference
Qe ReferenceQe Reference
Qe Reference
 
Whats new in ES2019
Whats new in ES2019Whats new in ES2019
Whats new in ES2019
 
Getting started with ES6
Getting started with ES6Getting started with ES6
Getting started with ES6
 

Mehr von Schalk Cronjé

DocuOps & Asciidoctor in a JVM World
DocuOps & Asciidoctor in a JVM WorldDocuOps & Asciidoctor in a JVM World
DocuOps & Asciidoctor in a JVM WorldSchalk Cronjé
 
What's new in Asciidoctor
What's new in AsciidoctorWhat's new in Asciidoctor
What's new in AsciidoctorSchalk Cronjé
 
Probability Management
Probability ManagementProbability Management
Probability ManagementSchalk Cronjé
 
Seeking Enligtenment - A journey of purpose rather than instruction
Seeking Enligtenment  - A journey of purpose rather than instructionSeeking Enligtenment  - A journey of purpose rather than instruction
Seeking Enligtenment - A journey of purpose rather than instructionSchalk Cronjé
 
Idiomatic Gradle Plugin Writing - GradleSummit 2016
Idiomatic Gradle Plugin Writing - GradleSummit 2016Idiomatic Gradle Plugin Writing - GradleSummit 2016
Idiomatic Gradle Plugin Writing - GradleSummit 2016Schalk Cronjé
 
Gradle in 45min - JBCN2-16 version
Gradle in 45min - JBCN2-16 versionGradle in 45min - JBCN2-16 version
Gradle in 45min - JBCN2-16 versionSchalk Cronjé
 
Cool Jvm Tools to Help you Test - Aylesbury Testers Version
Cool Jvm Tools to Help you Test - Aylesbury Testers VersionCool Jvm Tools to Help you Test - Aylesbury Testers Version
Cool Jvm Tools to Help you Test - Aylesbury Testers VersionSchalk Cronjé
 
Cool JVM Tools to Help You Test
Cool JVM Tools to Help You TestCool JVM Tools to Help You Test
Cool JVM Tools to Help You TestSchalk Cronjé
 
Using the Groovy Ecosystem for Rapid JVM Development
Using the Groovy Ecosystem for Rapid JVM DevelopmentUsing the Groovy Ecosystem for Rapid JVM Development
Using the Groovy Ecosystem for Rapid JVM DevelopmentSchalk Cronjé
 
Basic Gradle Plugin Writing
Basic Gradle Plugin WritingBasic Gradle Plugin Writing
Basic Gradle Plugin WritingSchalk Cronjé
 
Idiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingIdiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingSchalk Cronjé
 
Beyond Estimates - Probability Management
Beyond Estimates - Probability ManagementBeyond Estimates - Probability Management
Beyond Estimates - Probability ManagementSchalk Cronjé
 
Documentation An Engineering Problem Unsolved
Documentation  An Engineering Problem UnsolvedDocumentation  An Engineering Problem Unsolved
Documentation An Engineering Problem UnsolvedSchalk Cronjé
 
Idiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingIdiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingSchalk Cronjé
 
Gradle in a Polyglot World
Gradle in a Polyglot WorldGradle in a Polyglot World
Gradle in a Polyglot WorldSchalk Cronjé
 
Idiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingIdiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingSchalk Cronjé
 
Death of Agile : Welcome to Value-focused Testing
Death of Agile : Welcome to Value-focused TestingDeath of Agile : Welcome to Value-focused Testing
Death of Agile : Welcome to Value-focused TestingSchalk Cronjé
 

Mehr von Schalk Cronjé (20)

DocuOps & Asciidoctor in a JVM World
DocuOps & Asciidoctor in a JVM WorldDocuOps & Asciidoctor in a JVM World
DocuOps & Asciidoctor in a JVM World
 
DocuOps & Asciidoctor
DocuOps & AsciidoctorDocuOps & Asciidoctor
DocuOps & Asciidoctor
 
What's new in Asciidoctor
What's new in AsciidoctorWhat's new in Asciidoctor
What's new in Asciidoctor
 
Probability Management
Probability ManagementProbability Management
Probability Management
 
Seeking Enligtenment - A journey of purpose rather than instruction
Seeking Enligtenment  - A journey of purpose rather than instructionSeeking Enligtenment  - A journey of purpose rather than instruction
Seeking Enligtenment - A journey of purpose rather than instruction
 
Idiomatic Gradle Plugin Writing - GradleSummit 2016
Idiomatic Gradle Plugin Writing - GradleSummit 2016Idiomatic Gradle Plugin Writing - GradleSummit 2016
Idiomatic Gradle Plugin Writing - GradleSummit 2016
 
Gradle in 45min - JBCN2-16 version
Gradle in 45min - JBCN2-16 versionGradle in 45min - JBCN2-16 version
Gradle in 45min - JBCN2-16 version
 
Cool Jvm Tools to Help you Test - Aylesbury Testers Version
Cool Jvm Tools to Help you Test - Aylesbury Testers VersionCool Jvm Tools to Help you Test - Aylesbury Testers Version
Cool Jvm Tools to Help you Test - Aylesbury Testers Version
 
Cool JVM Tools to Help You Test
Cool JVM Tools to Help You TestCool JVM Tools to Help You Test
Cool JVM Tools to Help You Test
 
Using the Groovy Ecosystem for Rapid JVM Development
Using the Groovy Ecosystem for Rapid JVM DevelopmentUsing the Groovy Ecosystem for Rapid JVM Development
Using the Groovy Ecosystem for Rapid JVM Development
 
Gradle in 45min
Gradle in 45minGradle in 45min
Gradle in 45min
 
Basic Gradle Plugin Writing
Basic Gradle Plugin WritingBasic Gradle Plugin Writing
Basic Gradle Plugin Writing
 
Idiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingIdiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin Writing
 
Beyond Estimates - Probability Management
Beyond Estimates - Probability ManagementBeyond Estimates - Probability Management
Beyond Estimates - Probability Management
 
Documentation An Engineering Problem Unsolved
Documentation  An Engineering Problem UnsolvedDocumentation  An Engineering Problem Unsolved
Documentation An Engineering Problem Unsolved
 
Idiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingIdiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin Writing
 
Gradle in a Polyglot World
Gradle in a Polyglot WorldGradle in a Polyglot World
Gradle in a Polyglot World
 
Idiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingIdiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin Writing
 
Death of Agile : Welcome to Value-focused Testing
Death of Agile : Welcome to Value-focused TestingDeath of Agile : Welcome to Value-focused Testing
Death of Agile : Welcome to Value-focused Testing
 
Asciidoctor in 15min
Asciidoctor in 15minAsciidoctor in 15min
Asciidoctor in 15min
 

Generative Programming In The Large - Applied C++ meta-programming

  • 1. ACCU 2007 Generative Programming in the Large Applied meta-programming Schalk W. Cronjé ysb33r@gmail.com
  • 2. ACCU 2007 Even in this new millennium, many engineers will still build components that have very little reuse potential due to the inflexible way that they were constructed. This leads to excessive time required to adapt a component for usage in another system.
  • 3. ACCU 2007 The world of modern C++ Generative Programming is a vastly untapped field (we are just scraping the surface)
  • 4. ACCU 2007 Definition It is a software engineering paradigm where the aim is to automatically manufacture highly customised and optimised intermediate or end-products from elementary, reusable components by means of configuration knowledge. Implies Code Generation Domain-specific language Generic Techniques
  • 5. ACCU 2007 Elements of Generative Programming Problem space Solution space Configuration Knowledge Illegal feature combinations Default settings & dependencies Construction rules Optimisations Configured ComponentsDomain-specific concepts Features Generic Components
  • 7. ACCU 2007 For effective implementation there is one basic principle that encompasses most GP strategies: Dijkstra's Separation of Concerns This principle accepts the fact that we cannot deal with many issues at once and that important issues should be addressed with purpose.
  • 8. ACCU 2007 Key Code-level Strategies Develop elementary components as generic components Fully testable outside of the intended product configuration Configure these components using generated artefacts appropriate to the programming language Aim for zero cyclomatic-complexity in the generated artefacts Eliminate defects as early as possible
  • 9. ACCU 2007 In the large ... Generative C++ can lead to large number of configuration classes or meta-classes being generated. It is not uncommon to work with 50+ tag classes within a single type-list Effective integration of meta-programming, compile- time paradigms and run-time paradigms are required. Code-bloat must be avoided!
  • 10. ACCU 2007 Conventions For the examples assume that the following namespace aliases exist using namespace AccuConf; namespace mpl = AccuConf::mpl; namespace bmpl = boost::mpl; All code are implemented in namespace AccuConf.
  • 11. ACCU 2007 Building a rule evaluator (as an example of a generative library)
  • 12. ACCU 2007 Requirement #1: Solve complex boolean statements if (cond_A && cond_B || !cond_C) return outcome_A; else if (cond_D) return outcome_B; else return outcome_C;
  • 13. ACCU 2007 Requirement #2: Rule-types are defined in a DSL condition_expr: input: IP-address operation: == condition_expr: input: IP-address operation: in_netmask condition_expr: input: Email-address operation: regex_match
  • 14. ACCU 2007 Requirement #3: Short-circuit // Jump to evaluate !cond_C if (cond_A && !cond_A || !cond_C) // Never evaluate cond_D if( cond_B || !cond_B || cond_D) // Don't evalute cond_A twice if( cond_A || cond_A ) if( cond_A && cond_A )
  • 15. ACCU 2007 Requirement #4: Compile-time & run-time rules // Hard-code compile-time rule1 = cond_A && cond_B // Loaded at run-time rule2 = load_rule( "ip in FEFE::/64" );
  • 16. ACCU 2007 Requirement #5: Early enforcment Only allow attribute-operator combinations that have been defined in DSL Only allow attributes to be passed that were defined in DSL
  • 17. ACCU 2007 The conceptual evaluator Evaluating rules class Evaluator { public: /**Evaluates the rules against a supplied set * of attributes * @param A A collected set of attributes that will * be used as input to the rules. * @return The outcome associated with the rule * that triggered */ Outcome const& resolve( Properties const& A) const; };
  • 18. ACCU 2007 The conceptual evaluator Adding rules class Evaluator { public: Outcome const& resolve( Properties const& A) const; /**Adds a rule to the rule set * @param O The outcome to return if this rule * triggers * @param N The order of this rule in the ruleset * @param R the rule to add */ void add_rule( Outcome const& O,Order const& N,Rule const& R ); };
  • 19. ACCU 2007 Idiom #1: Generative Property Bag What does the Properties class look like?
  • 20. ACCU 2007 Properties class This can be implemented as a heap-based or a stack- based approach. Heap-based: More memory-efficient, only allocate stored attributes. Suffers heap-access penalty. Potential for heap fragmentation. Stack-based: Pre-allocate space for all attributes, even if not used.
  • 21. ACCU 2007 Heap-based Properties class Use boost::any to provide generic storage Use boost::map to provide conditional storage Index using meta-indexes template <typename GeneratedPropSet> class Properties { public: // To be implemented ... private: typedef std::map< int,boost::any > container_type; container_type m_attrs; };
  • 22. ACCU 2007 Generated Property Set struct prop { struct ip_addr { typedef IPAddress value_type; typedef to-be-decided valid_matches; }; struct email_addr { typedef std::string value_type; typedef to-be-decided valid_matches; }; typedef boost::mpl::vector< ip_addr, email_addr > valid_attrs; };
  • 23. ACCU 2007 Setting a Property template <typename GeneratedPropSet> class Properties { public: template <typename P> void set( typename mpl::property_value<P>::type const& ); private: typedef std::map< int,boost::any > container_type; }; Properties<prop> A; A.set< prop::ip_addr >( "192.168.1.1" );
  • 24. ACCU 2007 Implementing Property::set template <typename GeneratedPropSet> template <typename P> void Properties<GeneratedPropSet>::set( typename mpl::property_value<P>::type const& v_ ) { // Ensure that P is valid ! BOOST_MPL_ASSERT_MSG( (bmpl::contains< typename mpl::valid_properties< GeneratedPropSet >::type,P >::value), THIS_IS_NOT_A_VALID_PROPERTY, (P) ); // Rest to follow ... } Static Assertion provides relatively useful compile-time error if a invalid type is supplied
  • 25. ACCU 2007 Implementing Property::set template <typename GeneratedPropSet> template <typename P> void Properties<GeneratedPropSet>::set( typename mpl::property_value<P>::type const& v_ ) { // Ensure that P is valid ! BOOST_MPL_ASSERT_MSG( bmpl::contains< typename mpl::valid_properties< GeneratedPropSet >::type,P >::value, THIS_IS_NOT_A_VALID_PROPERTY, (P) ); // Rest to follow ... } boost::mpl::contains is a metapredicate that returns TRUE if P is in the list of valid properties
  • 26. ACCU 2007 Implementing Property::set template <typename GeneratedPropSet> template <typename P> void Properties<GeneratedPropSet>::set( typename mpl::property_value<P>::type const& v_ ) { // Ensure that P is valid ! BOOST_MPL_ASSERT_MSG( (bmpl::contains< typename mpl::valid_properties< GeneratedPropSet >::type,P >::value), THIS_IS_NOT_A_VALID_PROPERTY, (P) ); // Rest to follow ... } mpl::valid_properties is our own metaclass to extract the MPL sequence of valid property names from GeneratedPropSet
  • 27. ACCU 2007 Implementing Property::set template <typename GeneratedPropSet> template <typename P> void Properties<GeneratedPropSet>::set( typename mpl::property_value<P>::type const& v_ ) { BOOST_MPL_ASSERT_MSG( ... ); // Find key for map const int pos = mpl::property_pos< GeneratedPropSet, P >::value ; // Rest to follow ... } mpl::property_pos is our own metaclass returning the relative position of a type in a typelist. We use this value as a key into the map. Due to the MPL_ASSERT we can be ensured that this is a valid value.
  • 28. ACCU 2007 Implementing Property::set template <typename GeneratedPropSet> template <typename P> void Properties<GeneratedPropSet>::set( typename mpl::property_value<P>::type const& v_ ) { BOOST_MPL_ASSERT_MSG( ... ); // Find key for map const int pos = mpl::property_pos< GeneratedPropSet, P >::value ; // Rest to follow ... } Use of 'const int' allows for optimisation at compile-time
  • 29. ACCU 2007 Implementing Property::set template <typename GeneratedPropSet> template <typename P> void Properties<GeneratedPropSet>::set( typename mpl::property_value<P>::type const& v_ ) { BOOST_MPL_ASSERT_MSG( ... ); const int pos = ... ; // Assign the value typedef typename mpl::property_value<P>::type value_type; m_attrs[pos] = v_; }
  • 30. ACCU 2007 Implementing Property::set (alternative) template <typename GeneratedPropSet> template <typename P,typename V> void Properties<GeneratedPropSet>::set( V const& v_ ) { BOOST_MPL_ASSERT_MSG( ... ); const int pos = ... ; // Assign the value typedef typename mpl::property_value<P>::type value_type; m_attrs[pos] = value_type(v_); }
  • 31. ACCU 2007 Getting a Property template <typename GeneratedPropSet> class Properties { public: template <typename P> typename mpl::property_value<P>::type const& get() const; private: typedef std::map< int,boost::any > container_type; }; Properties<prop> A; A.set< prop::ip_addr >( "192.168.1.1" ); std::cout << A.get< prop::ip_addr >( );
  • 32. ACCU 2007 Implementing Property::get template <typename GeneratedPropSet> template <typename P> typename mpl::property_value<P>::type const& Properties<GeneratedPropSet>::get() const { BOOST_MPL_ASSERT_MSG( ... ); // Find key for map typename container_type::const_iterator itr = m_attrs.find( mpl::property_pos< GeneratedPropSet, P >::value ); // Rest to follow ... } Reusing mpl::property_pos we obtain an iterator to the appropiate property. Note the use of MPL_ASSERT to ensure a valid index value
  • 33. ACCU 2007 Implementing Property::get template <typename GeneratedPropSet> template <typename P> typename mpl::property_value<P>::type const& Properties<GeneratedPropSet>::get() const { BOOST_MPL_ASSERT_MSG( ... ); ... itr = m_attrs.find( ... ); if( m_attrs.end() == itr ) throw range_error("Property not set"); // Rest to follow ... } Throw an exception if the property is not set. Use Property::is_set predicate if a no_throw check is needed. (is_set implementation left as an exercise)
  • 34. ACCU 2007 Implementing Property::get template <typename GeneratedPropSet> template <typename P> typename mpl::property_value<P>::type const& Properties<GeneratedPropSet>::get() const { BOOST_MPL_ASSERT_MSG( ... ); ... itr = m_attrs.find( ... ); if( m_attrs.end() == itr ) ... ; typedef typename mpl::property_value<P>::type value_type; return *boost::any_cast<value_type> (&(itr->second)); } We can assume that the type stored is correct. Need to use the & to invoke a non-copy version of any_cast.
  • 35. ACCU 2007 Idiom #2: GGS Generic-Generated Separation: Access to generated typelists from generic code should go through metaclasses.
  • 36. ACCU 2007 MPL metaclasses Abstract access to type information through metaclasses This allows for specialisation when needed Improves long-term maintenance
  • 37. ACCU 2007 Obtaining the value_type template <typename Property> struct property_value { typedef typename Property::value_type type; };
  • 38. ACCU 2007 Sequence of Valid Properties template <typename Properties> struct valid_properties { typedef typename Properties::valid_properties type; };
  • 39. ACCU 2007 Property Position template <typename Properties,typename Property> struct valid_properties : bmpl::find< typename valid_properties< Properties>::type, Property >::type::pos { // Prevent invalid Property BOOST_MPL_ASSERT_MSG( bmpl::contains< typename valid_properties< Properties>::type, Property >::value, PROPERTY_NOT_FOUND_IN_SEQUENCE, (Property,Properties) ); };
  • 40. ACCU 2007 Idiom #3: Visit Each Apply an operation to each generated member
  • 41. ACCU 2007 Using Boost for_each bmpl::for_each< mpl::valid_properties<Properties>::type >( FUNCTOR() ); struct FUNCTOR { template <typename P> void operator()(P) const; }; For each type in sequence calls the functor
  • 42. ACCU 2007 Using Boost for_each bmpl::for_each< mpl::valid_properties<Properties>::type >( FUNCTOR() ); struct FUNCTOR { template <typename P> void operator()(P) const; }; Functor must be able to accommodate each type, otherwise compile-error will occur
  • 43. ACCU 2007 Using Boost for_each struct print_ip { Properties const& p; print_ip(Properties const& p_) : p(p_) {} template <typename P> void operator()(P) const {} void operator()(ip_addr) const {std::cout << p.get<ip_addr>();} }; bmpl::for_each< mpl::valid_properties<Properties>::type >( print_ip(my_properties) );
  • 44. ACCU 2007 Idiom #4: Type-erasure A known interface irrespective of the types used
  • 45. ACCU 2007 Rule Evaluation Signature template <typename Properties> bool Functor( Properties const& ); boost::function< bool(Properties const&) >
  • 46. ACCU 2007 Rule Class template <typename Properties> class Rule { public: // C-tors to follow ... Rule operator || (Rule const&) const; Rule operator && (Rule const&) const; Rule operator !() const; bool operator()(Properties const&) const; private: boost::function< bool(Properties const&) > m_rule; };
  • 47. ACCU 2007 Rule Class template <typename Properties> class Rule { public: template < typename Property, typename Operand > Rule( Operand<Property> const& op_ ); };
  • 48. ACCU 2007 Idiom #5: Hekaton Typelist Working around limitations in existing typelist libraries
  • 49. ACCU 2007 Limitations in Boost MPL sequences Maximum size of template parameter list is implementation-dependant Typically 20 GP might require very long lists 100 types are not uncommon A special type-list might be needed to convert a very long generated list into a standard Boost MPL sequence.
  • 50. ACCU 2007 Hekaton-typelist template < typename T0 = bmpl::na, typename T1 = bmpl::na, ..., typename T99 = bmpl::na > struct typelist { typedef bmpl::vector<T0,...,T19> _list0; typedef bmpl::vector<T20,...,T39> _list1; typedef bmpl::vector<T40,...,T59> _list2; // etc. // Join lists typedef bmpl::joint_view<_list0,_list1 > _join0; typedef bmpl::joint_view<_join0,_list2 > _join1; //etc. // until the last join which becomes typedef to-be-defined type; };
  • 51. ACCU 2007 Hekaton-typelist (detail) namespace detail { template < typename V0 = bmpl::vector<>, typename V1 = bmpl::vector<>, ..., typename V9 = bmpl::vector<> > struct typelist { // detail to follow ... }; } // namespace detail
  • 52. ACCU 2007 Hekaton-typelist (detail) namespace detail { #define P_LIST(z,n,t) BOOST_PP_COMMA_IF(n) typename V##n = t template < BOOST_PP_REPEAT(10,P_LIST,bmpl::vector<>) > struct typelist { // detail to follow ... }; #undef P_LIST } // namespace detail
  • 53. ACCU 2007 Hekaton-typelist (detail) namespace detail { #define P_LIST(z,n,t) BOOST_PP_COMMA_IF(n) typename V##n = t template < BOOST_PP_REPEAT(10,P_LIST,bmpl::vector<>) > struct typelist { typedef bmpl::joint_view<_V0,_V1 > _join0; typedef bmpl::joint_view<_join0,V2 > _join1; //etc. until the last join which becomes typedef bmpl::joint_view<_join8,V9 > type; }; #undef P_LIST } // namespace detail
  • 54. ACCU 2007 Hekaton-typelist (final) #define P_LIST1(z,n,t) BOOST_PP_COMMA_IF(n) typename T##n = t #define P_LIST2(z,n,t) BOOST_PP_COMMA_IF(n) t##n #define P_LIST3(z,n,t) BOOST_PP_COMMA_IF(n) t < BOOST_PP_REPEAT_FROM_TO( BOOST_PP_MUL(n,20), BOOST_PP_ADD(BOOST_PP_MUL(n,20),20), P_LIST2,T ) > template < BOOST_PP_REPEAT( 100,P_LIST1,bmpl::na ) > struct typelist : detail::typelist< BOOST_PP_REPEAT( 5,P_LIST3, bmpl::vector ) > ::type {}; #undef P_LIST1 #undef P_LIST2 #undef P_LIST3
  • 55. ACCU 2007 Idiom #6: Discriminant Union from Typelist boost::make_variant_over
  • 56. ACCU 2007 Discriminant Union typedef mpl::valid_properties<prop>::type example_typelist; typedef boost::make_variant_over< example_typelist >::type example_variant; X
  • 57. ACCU 2007 Discriminant Union struct extract_value_type { template <typename T> : mpl::property_value<T> struct apply {}; }; typedef boost::transform_view< mpl::valid_properties<prop>::type, extract_value_type >::type example_typelist typedef boost::make_variant_over< example_typelist >::type example_variant;
  • 59. ACCU 2007 Compiler Limitations Few compilers can handle the deep level of template instantiation very well gcc 4.x is fast VC 8 (VS2005) is adequate gcc 3.x is slow and has big memory footprint It is not always possible to use the puristic template solution Use the Boost Preprocessor Library Generate code of higher levels of cyclomatic- complexity
  • 61. ACCU 2007 Touching the void Pushing C++ skills far beyond the knowledge of many C++ practitioners Politics of introducing a new technology Teaches very good software skills outside the C++ domain Am I in the wrong language? (Yeah, thanks Kevlin!) Shows requirements for future languages Powerful syntax Simplicity of expression

Hinweis der Redaktion

  1. This is a very high level conceptual definition. Most engineers will be more concerned with the techniques for applying configuration knowledge to get to the solution
  2. The zero cyclomatic-complexity aim is the ideal. The real purpose is to eliminate any need to have to debug inside the generated code. This also makes a strong argument for the use of generic programming as an implementation strategy, as all the debugging can be done on the generic components even before anything has been generated.
  3. The zero cyclomatic-complexity aim is the ideal. The real purpose is to eliminate any need to have to debug inside the generated code. This also makes a strong argument for the use of generic programming as an implementation strategy, as all the debugging can be done on the generic components even before anything has been generated.
  4. It is totally possible to have different types depending on the platform. For instance it might be deemed to have WORD instead of uint16_t on a Win32 platform. Types, however, do not have to be OS-specific, types can be varied in order to obtain optimisations in specific products.
  5. It is totally possible to have different types depending on the platform. For instance it might be deemed to have WORD instead of uint16_t on a Win32 platform. Types, however, do not have to be OS-specific, types can be varied in order to obtain optimisations in specific products.