Boost logo

Boost :

Subject: Re: [boost] Units of data
From: Zachary Turner (divisortheory_at_[hidden])
Date: 2009-07-02 14:09:57


On Wed, Jul 1, 2009 at 11:26 PM, Steven Watanabe<watanabesj_at_[hidden]> wrote:
> AMDG
>
> Zachary Turner wrote:
>>
>> Thanks for your response.  I got this working mostly, but I'm still
>> having difficulty seeing how to tie it all together.  I added the
>> following:
>>
>> typedef boost::units::make_system<bit_base_unit>::type data_system;
>> typedef boost::units::unit<data_base_dimension::dimension_type,
>> data_system>    capacity;
>>
>> But I'm still not sure how to create and manipulate values with these
>> units.  For example, I can do:
>>
>> quantity<capacity> compressed_size;
>>
>> but if I try to assign it to anything I get errors.  I tried using the
>> BOOST_UNITS_STATIC_CONSTANT macro to create aliases such as bytes,
>> megabytes, etc but I think this is the wrong approach, is it because
>> all the units above are defined as base units?
>>
>> Ideally I want to be able to type:
>>
>> quantity<capacity> compressed_size = 10000 * bytes;
>>
>
> That won't quite work.  Implicit conversions are banned.
>
> typedef byte_base_unit::unit_type bytes;
>
> quantity<capacity> compressed_size(10000 * bytes());
>
> You can also use
> BOOST_UNITS_STATIC_CONSTANT(bytes, byte_base_unit::unit_type);
>
> to allow
> 10000 * bytes;
>
>> quantity<capacity> total_size = 400000 * bytes;
>>
>> float ratio = compressed_size / total_size;  //should be dimensionless
>>
>
> This ought to work.

Thanks for your help so far! I know I'm probably just making this too
difficult, but it's still not working. I guess I should just post a
complete sample so that we can eliminate the snip factor from the list
of possible causes (I put them in the boost namespace for the sake of
consistency but the same problem arises regardless).

//units.hpp

#ifndef UNITS_HPP_INCLUDED
#define UNITS_HPP_INCLUDED

#include <boost/units/base_dimension.hpp>
#include <boost/units/base_unit.hpp>
#include <boost/units/scale.hpp>
#include <boost/units/scaled_base_unit.hpp>
#include <boost/units/make_system.hpp>
#include <boost/units/static_constant.hpp>

#define DECLARE_BASE_UNIT_INFO(base_unit_, name_, symbol_) \
template<> struct base_unit_info<base_unit_> { \
        static const char* name() { return name_; } \
        static const char* symbol() { return symbol_; } \
};

namespace boost {

namespace units {

namespace data_capacity
{

struct data_capacity_base_dimension :
base_dimension<data_capacity_base_dimension, 73254> {};
typedef data_capacity_base_dimension::dimension_type data_capacity_dimension;

struct bit_base_unit : base_unit<bit_base_unit,
data_capacity_dimension, 76389> {};

typedef scaled_base_unit<bit_base_unit, scale<2, static_rational<3> >
> byte_base_unit;
typedef scaled_base_unit<byte_base_unit, scale<2, static_rational<10>
> > kilobyte_base_unit;
typedef scaled_base_unit<byte_base_unit, scale<2, static_rational<20>
> > megabyte_base_unit;
typedef scaled_base_unit<byte_base_unit, scale<2, static_rational<30>
> > gigabyte_base_unit;
typedef scaled_base_unit<byte_base_unit, scale<2, static_rational<40>
> > terabyte_base_unit;
typedef scaled_base_unit<byte_base_unit, scale<2, static_rational<50>
> > petabyte_base_unit;

}

DECLARE_BASE_UNIT_INFO(data_capacity::bit_base_unit, "bit", "b")
DECLARE_BASE_UNIT_INFO(data_capacity::byte_base_unit, "byte", "B")
DECLARE_BASE_UNIT_INFO(data_capacity::kilobyte_base_unit, "kilobyte", "KB")
DECLARE_BASE_UNIT_INFO(data_capacity::megabyte_base_unit, "megabyte", "MB")
DECLARE_BASE_UNIT_INFO(data_capacity::gigabyte_base_unit, "gigabyte", "GB")
DECLARE_BASE_UNIT_INFO(data_capacity::terabyte_base_unit, "terabyte", "TB")
DECLARE_BASE_UNIT_INFO(data_capacity::petabyte_base_unit, "petabyte", "PB")

namespace data_capacity {

typedef boost::units::make_system<bit_base_unit>::type data_capacity_system;
typedef boost::units::unit<data_capacity_base_dimension::dimension_type,
data_capacity_system> data_capacity;

BOOST_UNITS_STATIC_CONSTANT(bit, bit_base_unit::unit_type);
BOOST_UNITS_STATIC_CONSTANT(bits, bit_base_unit::unit_type);
BOOST_UNITS_STATIC_CONSTANT(byte, byte_base_unit::unit_type);
BOOST_UNITS_STATIC_CONSTANT(bytes, byte_base_unit::unit_type);
BOOST_UNITS_STATIC_CONSTANT(kilobyte, kilobyte_base_unit::unit_type);
BOOST_UNITS_STATIC_CONSTANT(kilobytes, kilobyte_base_unit::unit_type);
BOOST_UNITS_STATIC_CONSTANT(megabyte, megabyte_base_unit::unit_type);
BOOST_UNITS_STATIC_CONSTANT(megabytes, megabyte_base_unit::unit_type);
BOOST_UNITS_STATIC_CONSTANT(gigabyte, gigabyte_base_unit::unit_type);
BOOST_UNITS_STATIC_CONSTANT(gigabytes, gigabyte_base_unit::unit_type);
BOOST_UNITS_STATIC_CONSTANT(terabyte, terabyte_base_unit::unit_type);
BOOST_UNITS_STATIC_CONSTANT(terabytes, terabyte_base_unit::unit_type);
BOOST_UNITS_STATIC_CONSTANT(petabyte, petabyte_base_unit::unit_type);
BOOST_UNITS_STATIC_CONSTANT(petabytes, petabyte_base_unit::unit_type);

}
}
}

#endif

//test.cpp

#include "units.hpp"
#include <boost/units/quantity.hpp>

void foo()
{
        using boost::units::quantity;
        using namespace boost::units::data_capacity;

        //Both of these fail with the message that there is no
conversion to the destination
        //type because the construcor is explicit
        quantity<data_capacity> compressed_size = 1000 * bytes;
        quantity<data_capacity, int> compressed_size2 = 1000 * bytes;

        //Succeeds but gives a horribly long warning about conversion from
'double' to 'const int'
        //at file 'boost/units/detail/conversion_impl.hpp(342)', reference to
class template instantiation at
        //boost/units/quantity.hpp(182)
               quantity<data_capacity, int> compressed_size3(1000 * bytes);
}

>
>> quantity<time> duration = 300 * seconds;
>>
>> quantity<data_rate> = total_size / duration; //has dimensions
>> capacity/tim
>
> This should work if data_rate is defined correctly.
>
Hopefully once I get this working I'll be able to figure that one out on my own!

Thanks
Zach


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