Re: [histogram] discussion of accessor interface design

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Re: [histogram] discussion of accessor interface design

Boost - Dev mailing list
On 1/15/19 12:35 PM, Hans Dembinski via Boost wrote:

> Pros:
> - really terse
> - you can access methods on the pointee with x->method() as well! (useful when histogram counters are not PODs)
> - you can iterate over x to get the indices, for (auto i : x) { … } works

Doesn't range-for use operator* so you will get the values?

> - since x acts like an array to the indices, you can pass it to functions which accept ranges or iterators (it has .begin() and .end())
> - x can be (and is) enhanced with other useful methods
>    * x.bin(N) returns the current bin interval for the N-th axis, allowing you to access the central value, width, edges
>    * x.density() returns the current density (bin value divided by product of current bin widths)
> Cons:
> - *x and x[0] do completely different things: *x gives you the bin value, x[0] gives you the first index

An alternative is to rename x[i] to x.index(i).

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [histogram] discussion of accessor interface design

Boost - Dev mailing list
Hi Bjorn,

> On 28. Jan 2019, at 12:43, Bjorn Reese via Boost <[hidden email]> wrote:
>
> On 1/15/19 12:35 PM, Hans Dembinski via Boost wrote:
>
>> Pros:
>> - really terse
>> - you can access methods on the pointee with x->method() as well! (useful when histogram counters are not PODs)
>> - you can iterate over x to get the indices, for (auto i : x) { … } works
>
> Doesn't range-for use operator* so you will get the values?

indexed(…) has iterators which return "accessors" when they are dereferenced, which behave like pointers to the cell value. So you have to dereference twice to go from the original iterator to the value, instead of once.

Here is an example snippet:

for (auto x : indexed(h, coverage::all)) {
  std::cout << boost::format("%2i %2i: %i\n") % x.index(0) % x.index(1) % *x;
}

x is the accessor, *x gives the value. The pointer semantics are nice, because they allow easy access to methods of the value, which may be an accumulator instead of a simple integer or floating point type. You can access methods on the value like this x->value(), x->variance().

>> - since x acts like an array to the indices, you can pass it to functions which accept ranges or iterators (it has .begin() and .end())
>> - x can be (and is) enhanced with other useful methods
>>   * x.bin(N) returns the current bin interval for the N-th axis, allowing you to access the central value, width, edges
>>   * x.density() returns the current density (bin value divided by product of current bin widths)
>> Cons:
>> - *x and x[0] do completely different things: *x gives you the bin value, x[0] gives you the first index
>
> An alternative is to rename x[i] to x.index(i).

Yes, I changed that in the meantime, after my friends from the Scikit-HEP project http://scikit-hep.org convinced me that I am overusing operators here.

Best regards,
Hans

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost