[Boost-users] [boost] [type_erasure] Review started (July 18-27, 2012)

18 views
Skip to first unread message

Lorenzo Caminiti

unread,
Jul 18, 2012, 1:13:20 AM7/18/12
to bo...@lists.boost.org, boost-a...@lists.boost.org, boost...@lists.boost.org
Hello all,

*** The review of Steven Watanabe's proposed Boost.TypeErasure library
begins on July 18, 2012 and ends on July 27, 2012. ***

THE LIBRARY

C++ provides runtime polymorphism through virtual functions. They are
a very useful feature, but they do have some limitations.
* They are intrusive. In generic programming, we can design an
interface which allows third-party types to be adapted to it.
* They require dynamic memory management. Of course, most of the
problems can be avoided by using an appropriate smart pointer type.
Even so, it still acts like a pointer rather than a value.
* Virtual functions' ability to apply multiple independent concepts to
a single object is limited.
The Boost.TypeErasure library solves these problems allowing us to
mirror static generic programming at runtime.

Library source:
http://svn.boost.org/svn/boost/sandbox/type_erasure/

Pre-built documentation:
http://steven_watanabe.users.sourceforge.net/type_erasure/libs/type_erasure/

You can also download archives with pre-built documentation from:
http://sourceforge.net/projects/steven-watanabe.u/files/

YOUR REVIEW

Please submit a review to the mailing-list by replying to this email
("[boost] [type_erasure] Review ..." should be in the subject).

Please state clearly whether you think this library should be accepted
as a Boost library.

Other questions you may want to consider:
1. What is your evaluation of the design?
2. What is your evaluation of the implementation?
3. What is your evaluation of the documentation?
4. What is your evaluation of the potential usefulness of the library?
5. Did you try to use the library? With what compiler? Did you have
any problems?
6. How much effort did you put into your evaluation? A glance? A
quick reading? In-depth study?
7. Are you knowledgeable about the problem domain?

Thanks in advance to all who participate in the review discussion --
I'm looking forward to it!

The review manager.
--Lorenzo
_______________________________________________
Boost-users mailing list
Boost...@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users

Lorenzo Caminiti

unread,
Jul 23, 2012, 9:09:49 AM7/23/12
to bo...@lists.boost.org, boost-a...@lists.boost.org, boost...@lists.boost.org
Hello all,

On Wed, Jul 18, 2012 at 1:13 AM, Lorenzo Caminiti <lorca...@gmail.com> wrote:
> *** The review of Steven Watanabe's proposed Boost.TypeErasure library
> begins on July 18, 2012 and ends on July 27, 2012. ***

*** Boost.TypeErasure review ends in 5 days. Please submit your reviews :D ***

There have been interesting discussions on the library on the ML but I
have not received any official review yet :( Especially if you are a
user of Boost Any, Function, and Any Iterator, you definitely want to
take a look at Type Erasure as it generalizes solutions provided by
those other libraries.

Thank you.

The review manager.
--Lorenzo

Larry Evans

unread,
Jul 23, 2012, 3:37:05 PM7/23/12
to boost...@lists.boost.org, bo...@lists.boost.org
On 07/18/12 00:13, Lorenzo Caminiti wrote:
> Hello all,
>
> *** The review of Steven Watanabe's proposed Boost.TypeErasure library
> begins on July 18, 2012 and ends on July 27, 2012. ***
[snip]
http://steven_watanabe.users.sourceforge.net/type_erasure/libs/type_erasure/doc/html/boost_typeerasure/basic.html

contains a link, named boost::any, which sends my browser to:

http://steven_watanabe.users.sourceforge.net/type_erasure/libs/any/index.html

and that page shows:

An error has been encountered in accessing this page.

1. Server: steven_watanabe.users.sourceforge.net
2. URL path: /type_erasure/libs/any/index.html
3. Error notes: NONE
4. Error type: 404
5. Request method: GET
6. Request query string: NONE
7. Time: 2012-07-23 19:27:19 UTC (1343071639)

Larry Evans

unread,
Jul 23, 2012, 4:37:13 PM7/23/12
to boost...@lists.boost.org, bo...@lists.boost.org
On 07/18/12 00:13, Lorenzo Caminiti wrote:
> Hello all,
>
> *** The review of Steven Watanabe's proposed Boost.TypeErasure library
> begins on July 18, 2012 and ends on July 27, 2012. ***
>
The page:

http://steven_watanabe.users.sourceforge.net/type_erasure/libs/type_erasure/doc/html/boost_typeerasure/basic.html

says:

x is approximately equivalent to a boost::any

however, it doesn't say how te::any differs from boost::any.

The attached shows that a boost::any can change it's
type, and, as such, is somewhat like boost::variant.
However, te::any, once it's created, cannot change
it's type, AFAICT. At least that's what the
attached code indicates when compiled with:

#define SHOW_TE_FIXED_TYPE

With that #define, the error produced by gcc4.8 is:

../../../boost/type_erasure/any.hpp:702:9: note: mismatched types
'const boost::type_erasure::assignable<boost::type_erasure::_a, U>' and
'void'
_boost_type_erasure_assign_impl(
^

In contrast, without that #define, the boost::any has no problem
changing it's type and produces output:

typeinfo(bnd_value_ptr_v)=double*
typeinfo(bnd_displacement_v)=int
a_any=stk_displacement_v; any_cast<displacement_t>=0x97eb58
a_any=stk_value_ptr_v; any_cast<displacement_t>=0;
any_cast<value_ptr_t>=0x97eb78

The code uses a compiler specific demangler, also attached.

-regards,
Larry


demangled_type_name.hpp
any_conversion.cpp

Steven Watanabe

unread,
Jul 24, 2012, 10:16:47 AM7/24/12
to boost...@lists.boost.org
AMDG

On 07/23/2012 12:37 PM, Larry Evans wrote:
> On 07/18/12 00:13, Lorenzo Caminiti wrote:
>> Hello all,
>>
>> *** The review of Steven Watanabe's proposed Boost.TypeErasure library
>> begins on July 18, 2012 and ends on July 27, 2012. ***
> [snip]
> http://steven_watanabe.users.sourceforge.net/type_erasure/libs/type_erasure/doc/html/boost_typeerasure/basic.html
>
> contains a link, named boost::any, which sends my browser to:
>
> http://steven_watanabe.users.sourceforge.net/type_erasure/libs/any/index.html
>

The link would be correct if the library
were dropped into a boost distribution.
I'm ignoring this problem for now.

In Christ,
Steven Watanabe

Pete Bartlett

unread,
Jul 26, 2012, 5:19:28 PM7/26/12
to bo...@lists.boost.org, boost-a...@lists.boost.org, boost...@lists.boost.org
Lorenzo wrote:

>Hello all,
>*** Boost.TypeErasure review ends in 5 days. Please submit your reviews :D
***

> Library source:
> http://svn.boost.org/svn/boost/sandbox/type_erasure/

Just in case any other Boost SVN neophytes like me trying to get hold of
this - I'm finding that http anonymous access is not available, however
https access does work. The URL is otherwise identical.

Pete Bartlett

unread,
Jul 26, 2012, 8:01:16 PM7/26/12
to bo...@lists.boost.org, boost-a...@lists.boost.org, boost...@lists.boost.org
This is my review of the type erasure library following a relatively brief
look at it.

0) I vote to accept the library into Boost

1) Evaluation of design

I like it. The central class, any< mpl::vector< .. > >, is exactly what I'd
expect.
It is a mild shame that the notation for references is the old and familiar
boost::ref() style as used in several other Boost libraries, but accept this
is not technically possible.

2) Evaluation of implementation.

Not evaluated.

3) Evaluation of documentation.

As others have said, further examples will lower the learning curve.
Although the references section looks forbidding at first, my gut feel is
that it will be like other Boost libraries - the reference section only
"comes alive" when you know the library quite well and you just need to
remind yourself what is (and what isn't) available.

4) Usefulness

I think this enormous potential and would be very likely to use it my own
code. I've several times found that it would be nice to generalize
boost::function or adobe::any_iterator but never had the wherewithal to do
it well. For example a library I've been involved in had its own notion of a
"multi_function" like a boost::function<> but all instances had to support
multiple function signatures, This turned out to be almost trivial with
Boost.TypeErasure. A complete program listing follows:

#include <boost/type_erasure/any.hpp>
#include <boost/type_erasure/callable.hpp>
#include <boost/mpl/vector.hpp>
#include <iostream>

namespace mpl = boost::mpl;
using namespace boost::type_erasure;

typedef mpl::vector< copy_constructible<>
, typeid_<>
, callable< double(double) , const _self >
, callable< double(double,double) ,const _self >
> multi_function_concepts;

typedef any< multi_function_concepts , _self > non_ref_multi_function;
typedef any< multi_function_concepts , _self& > ref_multi_function;

template<typename RefInfo> double test_multi_function( any<
multi_function_concepts , RefInfo > const& mf )
{
return mf(3.0) + mf(1.0,2.0);
}

struct model_of_multi_function
{
typedef double state_t;
state_t m_state;

explicit model_of_multi_function(state_t state)
: m_state(state)
{
}

double operator()(double x) const
{
return m_state + x;
}

double operator()(double x, double y) const
{
return m_state*x*y;
}
};

int main()
{
model_of_multi_function m(5.0);
non_ref_multi_function x( m );
ref_multi_function y(m);

std::cout << "Result1 was : " << test_multi_function(x) << "\n";
std::cout << "Result2 was : " << test_multi_function(y) << "\n";
m.m_state = 6.0; //should not change state of x, should change state of y
std::cout << "Result3 was : " << test_multi_function(x) << "\n";
std::cout << "Result4 was : " << test_multi_function(y) << "\n";
}

>5. Did you try to use the library? With what compiler? Did you have any
problems?

Yes I tried to used the library to prove "multi_function" worked as above.
Compiled and ran only with VC10 - no problems to report.

>6. How much effort did you put into your evaluation? A glance? A quick
reading? In-depth study?

About 3 hours in total: playing with library, reading docs, reading test
code.

>7. Are you knowledgeable about the problem domain?

Only in so much that I'm one of many to think "what is the true
generalization of Boost.Function??". From my look this evening,
Boost.TypeErasure appears to be it.

One final point on the name. Paul Bristow wrote:
>PS I can't come up with a better name than TypeErasure but it is certainly
a bit forbidding :-)

I'd like to respectively disagree. My intuition notion of what the library
might be about having only heard the name turned out to match exactly with
what it can really do. That suggests it is a good name!
Unsubscribe & other changes:
http://lists.boost.org/mailman/listinfo.cgi/boost

Robert Jones

unread,
Jul 30, 2012, 5:04:50 AM7/30/12
to boost...@lists.boost.org
This isn't a review, mainly because I don't feel qualified to offer one, just a comment.

I don't really understand what difficulty this library is intended to solve, I've read the
comments about begin a generalisation of Any and Function, and Eric's naming
suggestions of Boost.Duck etc, but a single a example of coding conundrum for which
this library is a better, or only, solution would be hugely helpful.

Thanks, Rob.

Larry Evans

unread,
Aug 2, 2012, 3:29:44 PM8/2/12
to boost...@lists.boost.org, bo...@lists.boost.org
On 07/18/12 00:13, Lorenzo Caminiti wrote:
> Hello all,
>
> *** The review of Steven Watanabe's proposed Boost.TypeErasure library
> begins on July 18, 2012 and ends on July 27, 2012. ***
[snip]
Should type_erasure be accepted into Boost?

Answer:
No, not yet.
Why(in order of importance):

1) any<C,T>::any(U&, static_binding<Map>&) bug

The bug reported here:
http://article.gmane.org/gmane.comp.lib.boost.devel/233101
should be resolved.

The bug is just too dangerous for the resolution to be delayed.

2) any<C,T>::any(U&, binding<C>const&) documentation problem.

The vague documentation problem described below
( search for [vague:any<C,T>::any(U&, binding<C>const&)]:)
should be resolved first.

A novice user, such as myself, could easily misunderstand the
purpose of this constructor and spend hours before finally
stumbling upon the answer or pestering Steven for some
explanation. Solving this now would probably save future
novice users and probably Steven valuable time.

My review:

1. What is your evaluation of the design?

Good, except for:

[need variadic static_binding ctor]:

The any CTOR:

template<class U, class Map>
any(U & arg, const static_binding< Map > & binding);

documented here:


http://steven_watanabe.users.sourceforge.net/type_erasure/libs/type_erasure/doc/html/boost/type_erasure/any_Concept__T___id2445315.html#id2445396-bb

allows only a single argument to the constructor to the
underlying type. I'd suggest adding another CTOR with
interface:

template<class Map, class... U>
explicit any(const static_binding< Map > & binding, U &&... arg);

which is similar to:

explicit any(const binding< Concept > & binding, U &&... arg);

Then any constructor of the underlying could be used.

[too many any ctors]:

According to `grep -e ' any('`, there are more than 45 any
constructors. That many makes it hard for the novice to know
which one to use. The Design notes:


http://steven_watanabe.users.sourceforge.net/type_erasure/libs/type_erasure/doc/html/boost_typeerasure/design.html#boost_typeerasure.design.constructors

are some help, but those notes also mention ambiguities and
user rules, which sound like indications of usability problems
to me.

Why wouldn't the following ctors be sufficent to do all the
current any constructors do (except for maybe requiring more
typing and maybe more constructor calls)?

template
< class... U
>
any
( static_binding<Map>const&
, U&&...
);//kind=binding constructor

template
< class... U
>
any
( binding<Concept>const&
, U&&...
);//kind=dispatching constructor

template
< class Concept2
, class Tag2
>
any
( any<Concept2,Tag2>U&&
, static_binding<Map>const&
);//kind=converting constructor

template
< class Concept2
, class Tag2
>
any
( any<Concept2,Tag2>U&& u
, binding<Concept2>const&b=binding_of(u)
);//kind=converting constructor

Providing just these 4 constructors would improve the usabilty.
Of course, I'm probably missing something, and if so,
explaining why the above would not work in the Design notes
would be helpful.

2. What is your evaluation of the implementation?

[in-source comments]:
Very few in-source comments, as for example, the in the code:


http://steven_watanabe.users.sourceforge.net/type_erasure/boost/type_erasure/detail/normalize.hpp

there are no in-source comments. This lack of in-source comments
made it very hard to understand the implementation. There is also
no tests in the directory:



http://steven_watanabe.users.sourceforge.net/type_erasure/libs/type_erasure/test/

which contain any string with 'normalize' in it; hence, I assume
there are no unit tests for any class or function with normalize
as part of its name. Such unit tests, hopefully, would have
provided more information of the purpose of the code in
*/detail/normalize.hpp; hence, I'd recommend providing such tests
in addition to more in-source comments.

[any.hpp mysterious false?exp1:exp2 expr]:

In any.hpp, there's several expressions like:

false? this->_boost_type_erasure_deduce_constructor(arg...) : 0

Since:

false?exp1:exp2

always evaluates to exp2, this just obscures the code. It
should be replaced with exp2(i.e. 0) or some in-source comment
attached explaining why the ?: operator is needed.

3. What is your evaluation of the documentation?

Mostly good, but some documentation needs improvement.
For example:

[vague:rebinding_any.html]:

This doc:


http://steven_watanabe.users.sourceforge.net/type_erasure/libs/type_erasure/doc/html/boost/type_erasure/rebind_any.html

Claims rebind_any<Any,T>::type:

returns any type corresponding to a placeholder.

However, it doesn't say what the Any in rebind_any<Any,T> may be,
and if one assumes Any is a type_erasure::any<C,S> for some
concept, C, and placeholder, S, then that description makes no
sense because C does not contain any information about which
actual type is matched to which placeholder. That information is
only avaiable from the any<C,S> constructor arguments or from the
any<C,S>::table member variable, IIUC.

I would think example code illustrating the purpose might help.
There is an example here:


http://steven_watanabe.users.sourceforge.net/type_erasure/libs/type_erasure/doc/html/boost_typeerasure/concept.html#boost_typeerasure.concept.custom

and that shows Base as the Any arg in rebind_any.html. Now since
Base is a template arg to concept_interface, I have to look at the
concept_interface doc here:


http://steven_watanabe.users.sourceforge.net/type_erasure/libs/type_erasure/doc/html/boost/type_erasure/concept_interface.html

which says Base is:

The base of this class.

which is little help, which forces me to search elsewhere to
understand rebind_any. At this point I resorted to actually
writing code print printing out demangled names to help figure out
rebind_any. However, that failed to help either. At that point, I
gave up.

[vague:any<C,T>::any(U&, binding<C>const&)]:

The ref doc for this:


http://steven_watanabe.users.sourceforge.net/type_erasure/libs/type_erasure/doc/html/boost/type_erasure/any.html#id2445089-bb

contains:

Requires:
Concept must contain a matching instance of constructible.

with no definition of "matching". There is something about
"relaxed_match" documented here:


http://steven_watanabe.users.sourceforge.net/type_erasure/libs/type_erasure/doc/html/boost/type_erasure/relaxed_match.html

but that just contains:

In the presence of this concept, the requirement that all the
arguments to a function must match is relaxed.

from which I assume that "matching" means:

all the arguments to a function must match exactly.

But that still does not define what "match exactly" means. It
can't mean just what the c++ language standard:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3290.pdf

calls "Declaration matching" in section 13.2 because a type_erasure
concept includes the placeholders and surely "matching" doesn't
mean a placeholder is expected as the actual argument to a function
signature used in a concept definition.

Now, the placeholder doc:


http://steven_watanabe.users.sourceforge.net/type_erasure/libs/type_erasure/doc/html/boost/type_erasure/placeholder.html

contains:

For example, in the following,

any<copy_constructible<_a>, _a> x(1);

The library sees that we're constructing an any that uses the _a
placeholder with an int. Thus it binds _a to int and instantiates
copy_constructible<int>.

since, according to the source codesuggests that the concept(which
is part of copy_constructible):

constructible<_a(const _a&)>

would allow an _a to be copy constructed from another _a, or
based on the aforementioned placeholder.html page, it would an
instance of the type bound to _a (call it bound_a), to be copy
constructed from another instance of bound_a; however, the post
here:

http://article.gmane.org/gmane.comp.lib.boost.devel/233023

shows that's not the case. Only after several exchanges between
I and Steven in that thread, and the hint:

The library deals with either any's or
with the contained types, but not both,
depending on what layer you're looking at.
You're trying to mix the two.

from Steven, in the reply:

http://article.gmane.org/gmane.comp.lib.boost.devel/233067

did I finally conclude:

The placeholders in concepts do *not* stand for the bound types
but instead for the any's containing those bound types.

Which is similar to the conclusion which I posted here:

http://article.gmane.org/gmane.comp.lib.boost.devel/233078

Since the 233078 post got no replies, I assume that conclusion is
right. If so, then that should be made clear in the
documentation (including tutorials). In addition, the following
example code (and especially the comments), should reduce future
confusion on this topic:

/* {***any_ctor_kinds.cpp*** */
//Purpose:
// Demonstrate the different purposes of different
// "kinds" any CTOR's.
//References:
// [ConsKind]
//
http://steven_watanabe.users.sourceforge.net/type_erasure/libs/type_erasure/doc/html/boost_typeerasure/design.html#boost_typeerasure.design.constructors
#include <iostream>
#include <boost/type_erasure/any.hpp>
#include <boost/type_erasure/binding_of.hpp>
namespace mpl = boost::mpl;
using namespace boost::type_erasure;

template
< unsigned ThisId
>
struct v
{
};
int main()
{
typedef
mpl::vector
< copy_constructible<_a>
#define COPY_CTOR_V0
#ifdef COPY_CTOR_V0
, constructible<_a(v<0>const&)>
//allows y(a_binding, v0)
//(see below) to compile.
#endif
>
a_concept;
typedef
any
< a_concept
, _a
>
a_any;
v<0>
v0;
a_any
x
( v0
)
/**
* This CTOR does no dispatching, it simply
* calls the decltype(v0) CTOR with argument, v0.
*
* This is a binding constructor, as defined in [ConsKind].
*/
;
binding<a_concept>const&
a_binding=binding_of(x);
a_any
y
( a_binding
/**
* This makes this constructor a dispatching constructor,
* according to item 2 in the 2nd numbered list in [ConsKind].
*
* Hence, the args after this 1st arg must
* match one of the concepts in a_concept.
*/
#define PH2VALUE
#ifndef PH2VALUE
, x
//With this argument, this y declaration
//matches concept:
// constructible<_a(const _a&)>
//where the 1st _a must match decltype(y)
//(because that's what is being constructed),
//and the 2nd _a must match decltype(x)
//(because that's the only argument),
//and decltype(y) == decltype(x).
//
//Since constructible<_a(const_a&)>
//is included in copy_constructibe<_a>,
//and copy_constructibe<_a> is in a_concept,
//this will compile.
#else
, v0
//With this argument, this y declaration
//does not match concept:
// constructible<a_(const& _a)>
//because,
//but does match concept:
// constructible<_a(const& v<0>)>
//Hence, for this to compile, a_concept must
//include the latter concept.
#endif
)
;
return 0;
}

/* }***any_ctor_kinds.cpp*** */

If that conclusion is wrong, then the docs need to be modified
(I've no idea how) to clearly define "matching" as used in the
any.html#id2445089-bb reference.

[incomplete:tuple.html]:

The doc:


http://steven_watanabe.users.sourceforge.net/type_erasure/libs/type_erasure/doc/html/boost/type_erasure/tuple.html

makes no mention of how the binding produced by this call are
generated. Something like the following brief addtion would
answer that question:

The bindings for each any in the constructed tuple is generated
from, in essense, the mpl::map:

mpl::map
< mpl::pair<T,U>...
>

For eample, with:

tuple<C,T0,T1,...,Tn> t(u0,u1,...un);

the mpl::map used to generate the bindings for all of:

get<0>(t)
get<1>(t)
...
get<n>(t)

would be, essentially:

mpl::map
< mpl::pair<T0,decltype(u0)>
, mpl::pair<T1,decltype(u1)>
...
, mpl::pair<Tn,decltype(un)>
>

[missing:tutorial needs some Constructors Design notes]:

There are more than 40 any constructors. A novice user needs
these divided up by purpose so he can quickly find the
constructor he needs.

The Design notes here:


http://steven_watanabe.users.sourceforge.net/type_erasure/libs/type_erasure/doc/html/boost_typeerasure/design.html#boost_typeerasure.design.constructors

provide a classification of constructors according to their
purpose. This should be part of the tutorial or the tutorial
should provide a reference to this. In addition, the tutorial
or reference:


http://steven_watanabe.users.sourceforge.net/type_erasure/libs/type_erasure/doc/html/boost_typeerasure/reference.html#header.boost.type_erasure.any_hpp

should categorize the CTORS in different lists under subject
headings suggesting the purpose as described in the Design notes.
This list categorization would help a novice find the appropriate
CTOR.

4. What is your evaluation of the potential usefulness of the library?

I've not enough experience in the problem domain to make an
informed conclusion.

5. a) Did you try to use the library?

Yes.

b) With what compiler?


ftp://gcc.gnu.org/pub/gcc/snapshots/4.8-20120624/gcc-4.8-20120624.tar.bz2

c) Did you have any problems?

Yes, described as follows:

[obscure-errors]:

The biggest problem was understanding the compiler error
messages such as those shown here:

http://article.gmane.org/gmane.comp.lib.boost.devel/233026

which gives very little clue about what causes the problem,
which was using the any<Concept,PlaceHolder> CTOR taking a
binding<Concept> arg where Concept did not include
constructible<(PlacHolder(...)>.

Based on a this quote:

The Boost Concept Checking Library uses some standard C++
constructs to enforce early concept compliance and that
provides more informative error messages upon non-compliance.

from:


http://www.boost.org/doc/libs/1_50_0/libs/concept_check/concept_check.htm

maybe using concept_check would help provide clearer error
messages.

[any<C,T>::any(U&, static_binding<Map>&) bug]:

If U is not mpl::at<Map,T>::type, then U will be the contained
type, but will be treated as a mpl::at<Map,T>::type.

This error was acknowledged here:

http://article.gmane.org/gmane.comp.lib.boost.devel/233101

and a possble solution posted here:

http://article.gmane.org/gmane.comp.lib.boost.devel/233104


6. How much effort did you put into your evaluation?
A glance? A
quick reading?
In-depth study?

I studied it in-depth. By that I mean I read most of the docs, and
looked closely at some of the source, ran various tests to see what
the purpose of some functions were, and created an example program
using my own placeholders:

struct ph_leafs //placeholder for grammar terminals
: placeholder
{};

struct ph_roots //placeholder for grammar non-terminals
: placeholder
{};

struct ph_expr //placeholder for any grammar expresssion
: placeholder
{};

Which I then used to compile a type-erased grammar of sorts.

I also suggested a change to any.hpp as solution to the bug
in the any(U&, const static_binding<Map>&) constructor discussed
here:

http://article.gmane.org/gmane.comp.lib.boost.devel/233101

7. Are you knowledgeable about the problem domain?

No, thus more example uses in real world programs would have been
helpful.

Nathan Ridge

unread,
Aug 3, 2012, 3:04:12 AM8/3/12
to Boost Mailing List

> [any.hpp mysterious false?exp1:exp2 expr]:
>
> In any.hpp, there's several expressions like:
>
> false? this->_boost_type_erasure_deduce_constructor(arg...) : 0
>
> Since:
>
> false?exp1:exp2
>
> always evaluates to exp2, this just obscures the code. It
> should be replaced with exp2(i.e. 0) or some in-source comment
> attached explaining why the ?: operator is needed.

This use of the conditional operator is a technique to determine
the type of an expression without evaluating it. In this case,
"arg..." will never be evaluated (since it appears in a false
branch of a conditional expression), but its type will influence
the type of the entire conditional expression.

Eric Niebler explains this technique nicely in this article [1]
(see page 2 in particular).

Regards,
Nate

[1] http://www.artima.com/cppsource/foreach.html

Larry Evans

unread,
Aug 3, 2012, 6:39:29 AM8/3/12
to boost...@lists.boost.org
On 08/03/12 02:04, Nathan Ridge wrote:
>
>> [any.hpp mysterious false?exp1:exp2 expr]:
>>
>> In any.hpp, there's several expressions like:
>>
>> false? this->_boost_type_erasure_deduce_constructor(arg...) : 0
>>
>> Since:
>>
>> false?exp1:exp2
>>
>> always evaluates to exp2, this just obscures the code. It
>> should be replaced with exp2(i.e. 0) or some in-source comment
>> attached explaining why the ?: operator is needed.
>
> This use of the conditional operator is a technique to determine
> the type of an expression without evaluating it. In this case,
> "arg..." will never be evaluated (since it appears in a false
> branch of a conditional expression), but its type will influence
> the type of the entire conditional expression.
>
> Eric Niebler explains this technique nicely in this article [1]
> (see page 2 in particular).
>
> Regards,
> Nate
>
> [1] http://www.artima.com/cppsource/foreach.html
>
THANK YOU!

If any.hpp had used a macro, somewhat like the ENCODED_TYPEOF shown
here:

http://www.artima.com/cppsource/foreach2.html

including the comments explaining the purpose, the code would
have been easier to understand.

-regards,
Larry



with either the

Sergey Mitsyn

unread,
Aug 3, 2012, 5:32:03 PM8/3/12
to boost...@lists.boost.org
Hello,

Just some questions:

1) Missing #include <cassert> in "boost\type_erasure\detail\storage.hpp"

2) Maybe i'm missing something, but it feels like the library doesn't
support concept function arguments an return types that contain
placeholder as a template parameter. Imagine a concept that returns
"std::pair<TIterator, TIterator>", where TIterator is another any:



template<class TIterator, class C=_self>
struct foo_concept
{
typedef std::pair<TIterator, TIterator> result_type;
static result_type apply(C& c) {
return std::make_pair(c.begin(),c.end()); }
};




Probably the problem is with detail::rebind_placeholders_in_argument.
The expected behavior is replacing 'TIterator' with something like
'std::_Vector_iterator' (or what it should be in specific case), just
like mpl::lambda replaces its mpl::_N placeholders.

Also I cannot just replace std::pair with another any - I'm trying to
match the preexisting concepts.

I've put an example into attachment.


> 5. Did you try to use the library? With what compiler? Did you have
> any problems?

MSVC 9.0

> 6. How much effort did you put into your evaluation? A glance? A
> quick reading? In-depth study?

Several hours.

> 7. Are you knowledgeable about the problem domain?

Almost no.

--
------------
Sergey Mitsyn.
test.cpp

Steven Watanabe

unread,
Aug 4, 2012, 8:46:30 AM8/4/12
to boost...@lists.boost.org
AMDG

On 08/03/2012 02:32 PM, Sergey Mitsyn wrote:
> Hello,
>
> Just some questions:
>
> 1) Missing #include <cassert> in "boost\type_erasure\detail\storage.hpp"
>

This header doesn't use assert.

> 2) Maybe i'm missing something, but it feels like the library doesn't
> support concept function arguments an return types that contain
> placeholder as a template parameter. Imagine a concept that returns
> "std::pair<TIterator, TIterator>", where TIterator is another any:
>
>
>
> template<class TIterator, class C=_self>
> struct foo_concept
> {
> typedef std::pair<TIterator, TIterator> result_type;
> static result_type apply(C& c) {
> return std::make_pair(c.begin(),c.end()); }
> };
>
>
>
>
> Probably the problem is with detail::rebind_placeholders_in_argument.
> The expected behavior is replacing 'TIterator' with something like
> 'std::_Vector_iterator' (or what it should be in specific case), just
> like mpl::lambda replaces its mpl::_N placeholders.
>
> Also I cannot just replace std::pair with another any - I'm trying to
> match the preexisting concepts.
>
> I've put an example into attachment.
>

The library can't handle this without
special knowledge of std::pair. This
would mean creating some kind of extension
point, which I'm not willing to do at this point.

The easiest way to handle this particular
case is to use output parameters

template<class TIterator, class C = _self>
struct foo_concept {
static void apply(C&, TIterator&, TIterator&);
};

In Christ,
Steven Watanabe

Sergey Mitsyn

unread,
Aug 4, 2012, 11:47:05 AM8/4/12
to boost...@lists.boost.org
On 04.08.2012 16:46, Steven Watanabe wrote:
> AMDG
>
> On 08/03/2012 02:32 PM, Sergey Mitsyn wrote:
>> Hello,
>>
>> Just some questions:
>>
>> 1) Missing #include <cassert> in "boost\type_erasure\detail\storage.hpp"
>>
>
> This header doesn't use assert.

Sorry, my fault - being messing with headers a little.

>
>> 2) Maybe i'm missing something, but it feels like the library doesn't
>> support concept function arguments an return types that contain
>> placeholder as a template parameter. Imagine a concept that returns
>> "std::pair<TIterator, TIterator>", where TIterator is another any:
>>
>>
>>
>> template<class TIterator, class C=_self>
>> struct foo_concept
>> {
>> typedef std::pair<TIterator, TIterator> result_type;
>> static result_type apply(C& c) {
>> return std::make_pair(c.begin(),c.end()); }
>> };
>>
>>
>>
>>
>> Probably the problem is with detail::rebind_placeholders_in_argument.
>> The expected behavior is replacing 'TIterator' with something like
>> 'std::_Vector_iterator' (or what it should be in specific case), just
>> like mpl::lambda replaces its mpl::_N placeholders.
>>
>> Also I cannot just replace std::pair with another any - I'm trying to
>> match the preexisting concepts.
>>
>> I've put an example into attachment.
>>
>
> The library can't handle this without
> special knowledge of std::pair. This
> would mean creating some kind of extension
> point, which I'm not willing to do at this point.

Why is that? AFAIK it's rather easy to determine class template and
template arguments from its instantiation - by passing it to specialized
class template. The "recursive" argument rebinding comes out naturally.

Is there another problem?

>
> The easiest way to handle this particular
> case is to use output parameters
>
> template<class TIterator, class C = _self>
> struct foo_concept {
> static void apply(C&, TIterator&, TIterator&);
> };

Ok. Adapting to std::pair<iterator, iterator> return type can be done in
concept_interface specialization. Thanks.

>
> In Christ,
> Steven Watanabe
>


--
------------
Sergey Mitsyn.

Sergey Mitsyn

unread,
Aug 4, 2012, 11:53:22 AM8/4/12
to boost...@lists.boost.org

>>
>> The library can't handle this without
>> special knowledge of std::pair. This
>> would mean creating some kind of extension
>> point, which I'm not willing to do at this point.
>
> Why is that? AFAIK it's rather easy to determine class template and
> template arguments from its instantiation - by passing it to specialized
> class template. The "recursive" argument rebinding comes out naturally.
>
> Is there another problem?

Ok, probably I got it. Library needs to pass anys as void*, and it's
impossible to say how to convert arbitrary C<void*> to C<any<...>>.
Reply all
Reply to author
Forward
0 new messages