Boost logo

Boost Users :

Subject: Re: [Boost-users] Describing "traits" of a class's members
From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2013-02-27 20:39:47


AMDG

On 02/27/2013 04:49 PM, Chris Stankevitz wrote:
> On Wed, Feb 27, 2013 at 4:08 PM, Chris Stankevitz
> <chrisstankevitz_at_[hidden]> wrote:
>> Can you modify the attached program so that the object
>> TCPositionTraits holds all the traits for the TCPosition object. Not
>> just the traits for the "double" parameters, as is currently the case.
>> Notably missing from TCPositionTraits is a reference to
>> TCPosition::mSteps.
>
> Attached is an example of how do do this. Drawback: the
> TCPositionTraits object now has a lot of typing in it. And if/when
> you create another object (e.g. TCEmployeeTraits) you are going to
> have to do a lot of typing again. There will be a lot of code
> duplication.
>

Here's a rough sketch of an interface for
a completely different way of going about it.
I haven't filled out the implementation of
the two macros and for_each_with_traits,
but I believe that it is possible using Boost.Fusion.
The basic method would be to use BOOST_FUSION_DEFINE_STRUCT_INLINE
for TCCLASS, use some kind of template specialization
for TCMEMBERTRAITS to associate the trait with
the member and implement for_each_with_traits
using a combination of fusion zip, for_each,
and unfused.

template<class T>
struct TCTraits;

template<>
struct TCTraits<double>; // identical to TCDoubleTraits

TCCLASS(TCPosition,
  (double, mLatitude)
  (double, mAltitude)
  (unsigned, mSteps)
);

TCMEMBERTRAITS(TCPosition::mLatitude) = {
    "Latitude",
    "deg",
    5,
    180/Pi
};

TCMEMBERTRAITS(TCPosition::mAltitude) = {
    "Altitude",
    "m MSL"
};

TCMEMBERTRAITS(TCPosition::mSteps) = { "Steps" };

struct printer {
    bool WithLabel;
    bool WithUnits;
    typedef void result_type;
    template<class T>
    void operator()(const T& t, const TCTraits<T>& traits)
    {
        std::cout << traits.getString(t, WithLabel, WithUnits) << std::endl;
    }
};

template<class T>
void PrintValues(const T& t, bool WithLabel, bool WithUnits)
{
    for_each_with_traits(t, printer{WithLabel, WithUnits});
}

In Christ,
Steven Watanabe


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net