Sophie

Sophie

distrib > Mandriva > 9.1 > i586 > by-pkgid > b9ba69a436161613d8fb030c8c726a8e > files > 683

spirit-1.5.1-2mdk.noarch.rpm

// vim:ts=4:sw=4:et

#include <iostream>
#if defined(HAVE_BOOST)
#include <boost/thread/thread.hpp>
#endif
#if !defined(BOOST_HAS_THREADS)
int
main()
{
    std::cout << "/////////////////////////////////////////////////////////\n";
    std::cout << "\n";
    std::cout << "          object_with_id test (MT)\n";
    std::cout << "\n";
    std::cout << "/////////////////////////////////////////////////////////\n";
    std::cout << "\n";

    std::cout << "Test skipped\n";
    return 0;
};
#else

#undef SPIRIT_THREADSAFE
#define SPIRIT_THREADSAFE

#include <boost/spirit/core/impl/object_with_id.ipp>
#include <vector>
#include <algorithm>
#include <cassert>
#include <cstdlib>

using spirit::impl::object_with_id;

struct tag1 {};

typedef object_with_id<tag1> class1;

struct thread_test
{
    static unsigned int size() { return 1000000; }

    void run()
    { // create lots of objects
        v1.reserve(size());
        for (unsigned long i=0; i<size(); ++i)
        {
            //boost::thread().yield();
            v1.push_back(new class1);
        }
    }

    std::vector<class1*> v1;
};

struct test_wrapper
{
    test_wrapper(thread_test &t) : test(&t) {}
    test_wrapper(test_wrapper const &other) : test(other.test) {}
    ~test_wrapper() {}
    void operator()() const { test->run(); }
private:
    thread_test *test;
};

void
check_ascending(thread_test const &t)
{
    typedef std::vector<class1*>::const_iterator iter;
    iter p(t.v1.begin());
    iter const e(t.v1.end());
    iter n(p);

    while (++n!=e)
    {
        if ((**n).get_object_id()<=(**p).get_object_id())
        {
            using namespace std;
            cerr << "object ids out of order";
            exit(EXIT_FAILURE);
        }
        p = n;
    }
};

struct less1
{
    bool operator()(class1 const *p, class1 const *q) const
    {
        return p->get_object_id() < q->get_object_id();
    }
};

void
check_not_contained_in(
    thread_test const &candidate,
    thread_test const &in
)
{
    typedef std::vector<class1*>::const_iterator iter;
    iter p(candidate.v1.begin());
    iter const e(candidate.v1.end());

    while (p!=e)
    {
        iter found = std::lower_bound(in.v1.begin(),in.v1.end(),*p,less1());
        if  (found!=in.v1.end() &&
            (**found).get_object_id() == (**p).get_object_id())
        {
            using namespace std;
            cerr << "object ids not unique";
            exit(EXIT_FAILURE);
        }
        ++p;
    }
};

int
main()
{
    std::cout << "/////////////////////////////////////////////////////////\n";
    std::cout << "\n";
    std::cout << "          object_with_id test (MT)\n";
    std::cout << "\n";
    std::cout << "/////////////////////////////////////////////////////////\n";
    std::cout << "\n";

    thread_test test1; test_wrapper tw1(test1);
    thread_test test2; test_wrapper tw2(test2);
    thread_test test3; test_wrapper tw3(test3);

    boost::thread thread1(tw1);
    boost::thread thread2(tw2);
    boost::thread thread3(tw3);

    std::cout << "preparing ..." << std::flush;
    thread1.join();
    thread2.join();
    thread3.join();

    // now all objects should have unique ids, 
    // the ids must be ascending within each vector
    std::cout << "checking \n";

    assert(test1.v1.size()==thread_test::size());
    assert(test2.v1.size()==thread_test::size());
    assert(test3.v1.size()==thread_test::size());

    // check for ascending ids
    check_ascending(test1);
    check_ascending(test2);
    check_ascending(test3);

    //  check for uniqueness
    check_not_contained_in(test1,test3);
    check_not_contained_in(test1,test2);
    check_not_contained_in(test2,test1);
    check_not_contained_in(test2,test3);
    check_not_contained_in(test3,test2);
    check_not_contained_in(test3,test1);

    std::cout << "Test concluded successfully\n";
}

#endif