Boost logo

Boost :

From: jbandela_at_[hidden]
Date: 2001-01-25 21:24:01


Here is some code, that allows assigning and manipulating variables
without knowing the exact type, but by knowing what expression
produced them. For example, we can create iterators and iterator
through a vector, without referencing the vector::iterator type. Tell
me what your impressions of the code are, and if it is portable (I
tested in GCC and VC++). I think the most interesting snippet is
BOOST_TYPE, that allows you to get a null pointer of the type of an
expression without evaluating it.

Cheers,

John Bandela

#include <iostream>
#include<vector>

class Destructor{};

template<class T>
struct DestructorImp:public Destructor
{
        void* o;
        ~DestructorImp(){
                std::allocator<T> a;
                a.destroy(static_cast<T*>(o));
        }
};

template<class T>
DestructorImp<T> GetDestructor(void* o, const T*){
        DestructorImp<T> d;
        d.o = o;
        return d;
}

template<class T>
T* GetType(const T&){
        return 0;
}

template<int sz>
struct Memento{
        char mem_[sz];
        void* data_;

        template<class T>
        Memento(const T& object){
                T* o = new(static_cast<void*>(&mem_[0])) T(object);
                data_ = o;
                
        }
                
        template<class T>
        T& get(const T*){
                return *static_cast<T*>(data_);
        
        }
};

#define BOOST_TYPE(expr) (0?GetType((expr)):0)

#define BOOST_LET(var, expr,line) Memento<sizeof(expr)> var
(expr);Destructor dd##line = GetDestructor(var.data_,BOOST_TYPE
(expr)) ;
#define BOOST_GET(var,expr) var.get(BOOST_TYPE(expr))

int main(){
        using namespace std;
        double j = 2.3+3.2;
        
        BOOST_LET(x,j,0);
        
        cout << BOOST_GET(x,j);
        cout << x.get(BOOST_TYPE(j));
        
        std::vector<int> v;
        
        for(int i = 0; i < 10; ++i)
                v.push_back(i);
        
        BOOST_LET(y,v.begin(),1);
        for(;y.get(BOOST_TYPE(v.begin())) != v.end();++y.get
(BOOST_TYPE(v.begin())) )
                cout << *y.get(BOOST_TYPE(v.begin())) << "\n";
        

}


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