Boost logo

Boost :

Subject: Re: [boost] Heterogeneous Container Library (HCL) Feedback and Testing
From: James Armstrong (armstrhu_at_[hidden])
Date: 2015-06-03 18:12:49


On Wed, Jun 3, 2015 at 2:42 PM, Andrzej Krzemienski <akrzemi1_at_[hidden]>
wrote:

>
> Could you provide some sketch of a real life scenario? The examples show
> how I can use it, but I fail to imagine why I would need it. You mentioned
> storing the results of various DB queries, how would you make use of data
> stored in such way?
>
> Reards,
> &rzej
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>

I put together a simple example below. I have used a querying library that
returns results in a similar fashion.

// Define some classes
class Paper {//...};
class Notepad {//...};
class Folder {//...};
class Trash {//...};
class Cookie {//...};
class Candy {//...};
class Stapler {//...};
class Coin {//...};

class database
{
    public:
        enum class OBJECT_TYPES { PAPER, NOTEPAD, FOLDER, TRASH, COOKIE,
CANDY, STAPLER, COIN };

        bool peek()
        {
           return index >= data.size() ? false : true;
        }

        OBJECT_TYPES type(size_t column)
        {
           return types_[column];
        }

        template<typename T>
        T* next()
        {
           return static_cast<T*>( data[index++] );
        }

    private:
        std::vector<OBJECT_TYPES> types_;
        std::vector<void*> data;
        size_t index;
};

using drawer = std::vector<boost::any>;

bool add_object( drawer& D, database& db )
{
    if ( !db.peek() ) return false;

    switch ( db.type() )
    {
        case database::OBJECT_TYPES::PAPER:
           D.push_back( db.next<Paper>() );
           break;

       case database::OBJECT_TYPES::NOTEPAD:
           D.push_back( db.next<Notepad>() );
           break;

       case database::OBJECT_TYPES::FOLDER:
           D.push_back( db.next<Folder>() );
           break;

       // continue for all OBJECT_TYPES
    }

    return true;
}

int main()
{
    std::vector<drawer> cabinet;
    size_t num_drawers = 3;
    cabinet.resize(num_drawers);

    std::vector<database> db;
    db.resize(num_drawers);
    // connect to remote database and run query

    // pull results from database
    for (size_t d=0; d<num_drawers; ++d)
    {
       while( add_object(cabinet[d], db[d]) );
    }

    // parse cabinet objects below ...

    // Maybe, we want to count all loose change
    size_t money = 0;
    for (size_t d=0; d<num_drawers; ++d)
       for( auto iter = cabinet[d].begin<Coin>(); iter <
cabinet[d].end<Coin>; ++iter )
          money += *iter.value();

    std::cout << "Found " << money << " cents worth of loose change in
cabinet...Score!" << std::endl;

    return 0;
}

So yes, at some point you will need to know all object types that can be
returned as a result, but, one doesn't need to worry about all the types
that are actually returned as a result. Therefore, they can store all
possible objects in each of the drawers simply without having to say, my
drawer can hold Paper, Notepad, Folder, Trash, etc... and provides a clean
way to bundle all of these objects.

-- 
James Armstrong

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