[fusion] transform into vector

Hi, (Now my question was simplified.) How can a sequence object be transformed into fusion::vector object, keeping mutability of elements? For example, When at_c return type Sequence of input is: int&, char, double const&, ... , a type Sequence I need is: fusion::vector<result_of<F(int&)>::type, result_of<F(char)>::type, result_of<F(double const&)>::type, ...> Note that the output I need is not a fusion::transform_view but a fusion::vector. as_vector doens't work, because as_vector makes use of value_of. Am I missing some predefined function? Regards, -- Shunsuke Sogame

shunsuke wrote:
Hi,
(Now my question was simplified.) How can a sequence object be transformed into fusion::vector object, keeping mutability of elements?
For example,
When at_c return type Sequence of input is:
int&, char, double const&, ...
, a type Sequence I need is:
fusion::vector<result_of<F(int&)>::type, result_of<F(char)>::type, result_of<F(double const&)>::type, ...>
Note that the output I need is not a fusion::transform_view but a fusion::vector. as_vector doens't work, because as_vector makes use of value_of. Am I missing some predefined function?
I think you misunderstood some of my previous posts. value_of is only used to compute the desired result. There is actually no corresponding value_of function. It is only a metafunction, unlike /at/ which has both a result_of metafunction and a function. When the input sequence is actually traversed to generate the result, /at/ is the one being called. Hence, the sequence above is what is actually generated by as_vector. So, if you are sure that you have real l-values, the transform function: struct f { template <typename FunCall> struct result; template <typename Fun> struct result<Fun(int&)> { typedef int& type; }; template <typename Fun> struct result<Fun(int)> { typedef int& type; }; int& operator()(int& i) const { return i; } }; is perfectly safe. In fact, it won't compile if you do not have an lvalue. This won't compile if you give it an mpl::vector, for example (which doesn't have lvalue elements) because your operator() specifically asks for a reference. The second struct result<Fun(int)> is a pure-metafunction call called by value_at. You can read it as: the type will be an int& if the element type is an int -- it's a type only computation. It's unfortunate and a bit unintuitive to be using the result_of scheme to compute the value_at metafunction here. MPL uses the nested "apply" for this purpose. OTOH, it would be annoying to have to use "apply" for value_at and "result" for /at/. It's a compromise. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

Joel de Guzman wrote:
I think you misunderstood some of my previous posts. value_of is only used to compute the desired result. There is actually no corresponding value_of function. It is only a metafunction, unlike /at/ which has both a result_of metafunction and a function. When the input sequence is actually traversed to generate the result, /at/ is the one being called. Hence, the sequence above is what is actually generated by as_vector.
It's unfortunate and a bit unintuitive to be using the result_of scheme to compute the value_at metafunction here. MPL uses the nested "apply" for this purpose. OTOH, it would be annoying to have to use "apply" for value_at and "result" for /at/. It's a compromise.
I might probably understand this problem. transform_view, in order to implement `deref` etc, uses `result_of` in the standard manner, where `result<F(int)> means that rvalue is passed. But, as_vector applied to transform_view uses `result_of` in a strange manner through value_of. A FunctionObject for transform_view requires two result_of implementations; It seems impossible. Regards, -- Shunsuke Sogame

shunsuke wrote:
Joel de Guzman wrote:
I think you misunderstood some of my previous posts. value_of is only used to compute the desired result. There is actually no corresponding value_of function. It is only a metafunction, unlike /at/ which has both a result_of metafunction and a function. When the input sequence is actually traversed to generate the result, /at/ is the one being called. Hence, the sequence above is what is actually generated by as_vector.
It's unfortunate and a bit unintuitive to be using the result_of scheme to compute the value_at metafunction here. MPL uses the nested "apply" for this purpose. OTOH, it would be annoying to have to use "apply" for value_at and "result" for /at/. It's a compromise.
I might probably understand this problem.
transform_view, in order to implement `deref` etc, uses `result_of` in the standard manner, where `result<F(int)> means that rvalue is passed.
Correction: result<F(int&)> which means lvalue is passed. The lvalue is correctly propagated through the transform.
But, as_vector applied to transform_view uses `result_of` in a strange manner through value_of.
A FunctionObject for transform_view requires two result_of implementations; It seems impossible.
I provided an example, didn't I? Actually, there's another way to do it -- take a look at how fusion zip does it. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

Joel de Guzman wrote:
transform_view, in order to implement `deref` etc, uses `result_of` in the standard manner, where `result<F(int)> means that rvalue is passed.
Correction: result<F(int&)> which means lvalue is passed. The lvalue is correctly propagated through the transform.
No. By the standard, `result<F(int)>` means that rvalue is passed, and `result<F(T&)>` means that lvalue is passed.
But, as_vector applied to transform_view uses `result_of` in a strange manner through value_of.
A FunctionObject for transform_view requires two result_of implementations; It seems impossible.
I provided an example, didn't I?
That doesn't work with rvalues. With regard to standard manner, result<> implementation of `f` is wrong. So, that does't work with transform_view.
Actually, there's another way to do it -- take a look at how fusion zip does it.
I will apply that way(Preprocessor programming) if no workaround is found. Regards, -- Shunsuke Sogame

shunsuke wrote:
Joel de Guzman wrote:
transform_view, in order to implement `deref` etc, uses `result_of` in the standard manner, where `result<F(int)> means that rvalue is passed. Correction: result<F(int&)> which means lvalue is passed. The lvalue is correctly propagated through the transform.
No. By the standard, `result<F(int)>` means that rvalue is passed, and `result<F(T&)>` means that lvalue is passed.
Exactly! And, again, `deref` uses `result<F(T&)>` --as expected.
But, as_vector applied to transform_view uses `result_of` in a strange manner through value_of.
A FunctionObject for transform_view requires two result_of implementations; It seems impossible. I provided an example, didn't I?
That doesn't work with rvalues.
Of course it does :-) Did you try it? The example I attached (in the trac ticket) can even work with mpl::vector.
With regard to standard manner, result<> implementation of `f` is wrong. So, that does't work with transform_view.
Actually, there's another way to do it -- take a look at how fusion zip does it.
I will apply that way(Preprocessor programming) if no workaround is found.
Again, see fusion zip. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

Joel de Guzman wrote:
No. By the standard, `result<F(int)>` means that rvalue is passed, and `result<F(T&)>` means that lvalue is passed.
Exactly! And, again, `deref` uses `result<F(T&)>` --as expected.
I should say Yes! :-) BTW, result<F(int)> may be called from deref in case of sequence of rvalues.
But, as_vector applied to transform_view uses `result_of` in a strange manner through value_of.
A FunctionObject for transform_view requires two result_of implementations; It seems impossible. I provided an example, didn't I? That doesn't work with rvalues.
Of course it does :-) Did you try it? The example I attached (in the trac ticket) can even work with mpl::vector.
Ah, yes. I said about `f` in this thread.
Again, see fusion zip.
My range zipper is used like this: `my_zip(fusion::make_list(std::string("abc"),std::string("123"))`. Again, I place this simple question: When at_c return type Sequence of input is: int&, char, double const&, ... , how can I create fusion::vector<result_of<F(int&)>::type, result_of<F(char)>::type, result_of<F(double const&)>::type, ...> ? Regards, -- Shunsuke Sogame

shunsuke wrote:
Again, I place this simple question:
When at_c return type Sequence of input is:
int&, char, double const&, ...
, how can I create
fusion::vector<result_of<F(int&)>::type, result_of<F(char)>::type, result_of<F(double const&)>::type, ...>
What's the input sequence? Better yet, can you give me a simplified test case and the desired result? Let's work on this off-list. I'm really interested in providing a better solution or to make fusion better in this regard. Please CC Dan Marsden. Regar4ds, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

Joel de Guzman wrote:
shunsuke wrote:
I might probably understand this problem.
transform_view, in order to implement `deref` etc, uses `result_of` in the standard manner, where `result<F(int)> means that rvalue is passed.
Correction: result<F(int&)> which means lvalue is passed. The lvalue is correctly propagated through the transform.
But, as_vector applied to transform_view uses `result_of` in a strange manner through value_of.
A FunctionObject for transform_view requires two result_of implementations; It seems impossible.
I provided an example, didn't I? Actually, there's another way to do it -- take a look at how fusion zip does it.
Ok, tell you what: I understand the confusion. If you or anyone else can find a way to do value_at that passes the exact underlying element (undecorated) type, through the transform function, then, I'd gladly rethink this matter. Here's a possibility: struct identity { template <class FunCall> struct result; template <class Fun, class T> struct result<Fun(T&)> { typedef T& type; }; template <class T> struct value { typedef T& type; }; template <class T> T& operator()(T& v) const { return v; } }; That would add another requirement to the PolymorphicFunctionObject concept though and is not compatible with prior schemes. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

Joel de Guzman wrote:
Ok, tell you what: I understand the confusion. If you or anyone else can find a way to do value_at that passes the exact underlying element (undecorated) type, through the transform function, then, I'd gladly rethink this matter. Here's a possibility:
struct identity { template <class FunCall> struct result;
template <class Fun, class T> struct result<Fun(T&)> { typedef T& type; };
template <class T> struct value { typedef T& type; };
template <class T> T& operator()(T& v) const { return v; } };
I think this is not a good solution. If we are following Boost.Iterator's way, "value concept" should be placed in not FunctionObject but in transform_view. Because boost::transform_iterator can't always determine its `value_type` or `reference` from FunctionObject, you can pass explicitly `value_type` and `reference` type to boost::transform_iterator. Say, template<class Seq, class F, class ResultOfDeref = use_default, class ValueOf = use_default> struct transform_view; seems better. Regards, -- Shunsuke Sogame

shunsuke wrote:
If we are following Boost.Iterator's way, "value concept" should be placed in not FunctionObject but in transform_view. Because boost::transform_iterator can't always determine its `value_type` or `reference` from FunctionObject, you can pass explicitly `value_type` and `reference` type to boost::transform_iterator.
Say,
template<class Seq, class F, class ResultOfDeref = use_default, class ValueOf = use_default> struct transform_view;
Cool! I assume ResultOfDeref and ValueOf are metafunctions? Let's continue this discussion off-list. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net
participants (2)
-
Joel de Guzman
-
shunsuke