Boost logo

Boost :

Subject: Re: [boost] Formal review for QVM
From: Emil Dotchevski (emildotchevski_at_[hidden])
Date: 2015-12-14 15:53:22


On Mon, Dec 14, 2015 at 4:46 AM, Agustín K-ballo Bergé <
kaballo86_at_[hidden]> wrote:

> On 12/13/2015 9:07 PM, Emil Dotchevski wrote:
>
>> On Sun, Dec 13, 2015 at 1:16 PM, Agustín K-ballo Bergé <
>> kaballo86_at_[hidden]> wrote:
>>
>> On 12/13/2015 5:13 PM, Emil Dotchevski wrote:
>>>
>>> Yes, I'm interested to understand what brought this comment, though I am
>>>> not sure that there is a solution. The problem is that QVM can't invoke
>>>> constructors (other than the default constructor) for user-defined
>>>> types,
>>>> because different types could have different constructors (believe me,
>>>> I've
>>>> seen game programmers define some crazy matrix/vector constructors).
>>>> Because functions like normalized() operate on user-defined types, they
>>>> use
>>>> the default constructor to make a local object before returning it by
>>>> value.
>>>>
>>>>
>>> There's always the copy constructor, which I believe is already
>>> implicitly
>>> required by the library. Have you experimented with this before?
>>>
>>>
>> Actually, there might not be a copy constructor. In QVM views are
>> non-copyable. For example the return type of qvm::row and qvm::col, which
>> present a row or a column of a matrix as a vector, return non-copyable
>> types (which are still valid arguments for the normalized() function in
>> question.)
>>
>
> That's odd, views as I know them are copyable and cheaply so, since they
> are shallow. I would expect those views you mention not only to be
> copyable, but to be trivially-copyable. Could you expand on that?
>

In QVM views do not create temps, they are similar to static type casts and
have zero abstraction penalty (assuming inlining works).

For example, look at the "col" view, which accesses a matrix column as a
vector:
https://github.com/zajo/boost-qvm/blob/master/libs/qvm/include/boost/qvm/map_mv.hpp#L23#L141.
Near the top of the selection you'll see a col_ template and its traits,
then the col function itself looks like this:

template <int Col,class A>
typename boost::enable_if_c<
    is_m<A>::value,
    qvm_detail::col_<Col,A> &>::type
BOOST_QVM_INLINE_TRIVIAL
col( A & a )
    {
    return reinterpret_cast<typename qvm_detail::col_<Col,A> &>(a);
    }

The col_ class template itself isn't copyable because there is no object to
copy -- the returned reference refers to the argument of the user-defined
matrix type A used to instantiate the col function template.

> Anyways, I imagine calling `normalized` with one of those views either
> won't return something of that view's type, or it won't default-construct a
> view. Am I close here?
>

Calling normalized() on a view returns a type deduced by deduce_v, the
default for views being a compatible instantiation of the qvm::vec<>
template. Such types are required to be copyable and to have accessible
default constructor.

> if the compiler says there is an error here because `normalized` needs a
> default constructor, I'm gonna start suspecting something wrong is going on
> with the library. This is what I would naively expect `normalized` to be
> doing:
>
> template <typename Vec>
> Vec normalized(Vec v) {
> return v /= length(v);
> }
>

It can't be implemented that way because the type of the argument might not
be copyable.

Emil


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk