test_containers.cc
Go to the documentation of this file.
00001 #include <boost/test/auto_unit_test.hpp>
00002 #include <vector>
00003 
00004 #include <test/testsuite.hh>
00005 #include <typelib/utilmm/configset.hh>
00006 #include <typelib/pluginmanager.hh>
00007 #include <typelib/importer.hh>
00008 #include <typelib/typemodel.hh>
00009 #include <typelib/registry.hh>
00010 #include <typelib/value.hh>
00011 #include <typelib/value_ops.hh>
00012 #include "test_cimport.1"
00013 #include <string.h>
00014 using namespace Typelib;
00015 using namespace std;
00016 
00017 template<int ptrsize> struct ptr_value_getter { };
00018 template<> struct ptr_value_getter<4> { typedef uint32_t result; };
00019 template<> struct ptr_value_getter<8> { typedef uint64_t result; };
00020 
00021 typedef ptr_value_getter<sizeof(void*)>::result ptr_value_t;
00022 ptr_value_t ptr_value(void* ptr) { return reinterpret_cast<ptr_value_t>(ptr); };
00023 
00024 BOOST_AUTO_TEST_CASE( test_vector_assumptions )
00025 {
00026     // It is expected that ->size() depends on the type of the vector elements,
00027     // but that the size can be offset by using the ratio of sizeof()
00028     {
00029         vector<int32_t> values;
00030         values.resize(10);
00031         BOOST_REQUIRE_EQUAL(10, values.size());
00032         BOOST_REQUIRE_EQUAL(5, reinterpret_cast< vector<int64_t>& >(values).size());
00033     }
00034     {
00035         vector< vector<double> > values;
00036         values.resize(10);
00037         BOOST_REQUIRE_EQUAL(10, values.size());
00038         BOOST_REQUIRE_EQUAL(10 * sizeof(vector<double>), reinterpret_cast< vector<int8_t>& >(values).size());
00039     }
00040 
00041     // To resize the containers efficiently, we assume that moving the bytes
00042     // around is fine. This is a valid assumption only if the std::vector's
00043     // internal structure does not store any pointer to the memory location
00044     // 
00045     // This tests that this assumption is valid
00046     {
00047         vector< vector<double> > values;
00048         values.resize(10);
00049 
00050         uint8_t* values_p = reinterpret_cast<uint8_t*>(&values);
00051         uint8_t* it_p     = reinterpret_cast<uint8_t*>(&values);
00052         ptr_value_t vector_min = ptr_value(&values);
00053         ptr_value_t vector_max = ptr_value(&values) + sizeof(values);
00054 
00055         while ((it_p + sizeof(void*)) - values_p < static_cast<int>(sizeof(values)))
00056         {
00057             ptr_value_t p = *reinterpret_cast<ptr_value_t*>(it_p);
00058             BOOST_REQUIRE(!(p >= vector_min && p < vector_max));
00059             ++it_p;
00060         }
00061     }
00062 }
00063 
00064 static void import_test_types(Registry& registry)
00065 {
00066     static const char* test_file = TEST_DATA_PATH("test_cimport.tlb");
00067 
00068     utilmm::config_set config;
00069     PluginManager::self manager;
00070     auto_ptr<Importer> importer(manager->importer("tlb"));
00071     BOOST_REQUIRE_NO_THROW( importer->load(test_file, config, registry) );
00072 }
00073 
00074 struct AssertValueVisit : public ValueVisitor
00075 {
00076     vector<int32_t> values;
00077     bool visit_(int32_t& v)
00078     {
00079         values.push_back(v);
00080         return true;
00081     }
00082 };
00083 
00084 BOOST_AUTO_TEST_CASE( test_vector_defines_aliases )
00085 {
00086     Registry registry;
00087     import_test_types(registry);
00088     registry.alias("/B", "/BAlias");
00089     Container const& container = Container::createContainer(registry, "/std/vector", *registry.get("B"));
00090 
00091     Type const* aliased = registry.get("/std/vector</BAlias>");
00092     BOOST_REQUIRE(aliased);
00093     BOOST_REQUIRE(*aliased == container);
00094 }
00095 
00096 BOOST_AUTO_TEST_CASE( test_vector_getElementCount )
00097 {
00098     Registry registry;
00099     import_test_types(registry);
00100     Container const& container = Container::createContainer(registry, "/std/vector", *registry.get("B"));
00101 
00102     std::vector<B> vector;
00103     vector.resize(10);
00104     BOOST_REQUIRE_EQUAL(10, container.getElementCount(&vector));
00105 }
00106 
00107 BOOST_AUTO_TEST_CASE( test_vector_init_destroy )
00108 {
00109     Registry registry;
00110     import_test_types(registry);
00111     Container const& container = Container::createContainer(registry, "/std/vector", *registry.get("B"));
00112     BOOST_REQUIRE_EQUAL(Type::Container, container.getCategory());
00113 
00114     void* v_memory = malloc(sizeof(std::vector<B>));
00115     container.init(v_memory);
00116     BOOST_REQUIRE_EQUAL(0, container.getElementCount(v_memory));
00117     container.destroy(v_memory);
00118     free(v_memory);
00119 }
00120 
00121 BOOST_AUTO_TEST_CASE( test_vector_push )
00122 {
00123     Registry registry;
00124     import_test_types(registry);
00125     Container const& container = Container::createContainer(registry, "/std/vector", *registry.get("int"));
00126 
00127     std::vector<int> vector;
00128     for (int value = 0; value < 10; ++value)
00129     {
00130         container.push(&vector, Value(&value, container.getIndirection()));
00131         BOOST_REQUIRE_EQUAL(value + 1, vector.size());
00132 
00133         for (int i = 0; i < value; ++i)
00134             BOOST_REQUIRE_EQUAL(i, vector[i]);
00135     }
00136 }
00137 
00138 BOOST_AUTO_TEST_CASE( test_vector_erase )
00139 {
00140     Registry registry;
00141     import_test_types(registry);
00142     Container const& container = Container::createContainer(registry, "/std/vector", *registry.get("int"));
00143 
00144     std::vector<int> vector;
00145     for (int value = 0; value < 10; ++value)
00146         vector.push_back(value);
00147 
00148     int value = 20;
00149     BOOST_REQUIRE(!container.erase(&vector, Value(&value, container.getIndirection())));
00150     value = 5;
00151     BOOST_REQUIRE(container.erase(&vector, Value(&value, container.getIndirection())));
00152 
00153     BOOST_REQUIRE_EQUAL(9, vector.size());
00154     for (int i = 0; i < 5; ++i)
00155         BOOST_REQUIRE_EQUAL(i, vector[i]);
00156     for (int i = 5; i < 9; ++i)
00157         BOOST_REQUIRE_EQUAL(i + 1, vector[i]);
00158 }
00159 
00160 bool test_delete_if_pred(Value v)
00161 {
00162     int* value = reinterpret_cast<int*>(v.getData());
00163     return (*value > 3) && (*value < 6);
00164 }
00165 BOOST_AUTO_TEST_CASE( test_vector_delete_if )
00166 {
00167     Registry registry;
00168     import_test_types(registry);
00169     Container const& container = Container::createContainer(registry, "/std/vector", *registry.get("int"));
00170 
00171     std::vector<int> vector;
00172     for (int value = 0; value < 10; ++value)
00173         vector.push_back(value);
00174 
00175     container.delete_if(&vector, test_delete_if_pred);
00176 
00177     BOOST_REQUIRE_EQUAL(8, vector.size());
00178     for (int i = 0; i < 4; ++i)
00179         BOOST_REQUIRE_EQUAL(i, vector[i]);
00180     for (int i = 4; i < 8; ++i)
00181         BOOST_REQUIRE_EQUAL(i + 2, vector[i]);
00182 }
00183 
00184 BOOST_AUTO_TEST_CASE( test_vector_getElement )
00185 { 
00186     Registry registry;
00187     import_test_types(registry);
00188 
00189     Container const& container = Container::createContainer(registry, "/std/vector", *registry.get("int32_t"));
00190 
00191     std::vector<int32_t> v;
00192     v.resize(10);
00193     for (int i = 0; i < 10; ++i)
00194         v[i] = i;
00195 
00196     for (int i = 0; i < 10; ++i)
00197         BOOST_REQUIRE_EQUAL(i, *reinterpret_cast<int*>(container.getElement(&v, i).getData()));
00198 }
00199 
00200 BOOST_AUTO_TEST_CASE( test_vector_setElement )
00201 { 
00202     Registry registry;
00203     import_test_types(registry);
00204 
00205     Container const& container = Container::createContainer(registry, "/std/vector", *registry.get("int32_t"));
00206 
00207     std::vector<int32_t> v;
00208     v.resize(10);
00209 
00210     for (int i = 0; i < 10; ++i)
00211         container.setElement(&v, i, Typelib::Value(&i, container.getIndirection()));
00212 
00213     for (int i = 0; i < 10; ++i)
00214         BOOST_REQUIRE_EQUAL(i, v[i]);
00215 }
00216 
00217 BOOST_AUTO_TEST_CASE( test_vector_visit )
00218 { 
00219     Registry registry;
00220     import_test_types(registry);
00221 
00222     Container const& container = Container::createContainer(registry, "/std/vector", *registry.get("int32_t"));
00223 
00224     std::vector<int32_t> v;
00225     v.resize(10);
00226     for (int i = 0; i < 10; ++i)
00227         v[i] = i;
00228     BOOST_REQUIRE_EQUAL(10, container.getElementCount(&v));
00229 
00230     // Try visiting the value
00231     Value value(&v, container);
00232     AssertValueVisit visitor;
00233     visitor.apply(value);
00234 
00235     BOOST_REQUIRE_EQUAL(10, visitor.values.size());
00236     for (int i = 0; i < 10; ++i)
00237         BOOST_REQUIRE_EQUAL(i, visitor.values[i]);
00238 }
00239 
00240 BOOST_AUTO_TEST_CASE( test_erase_collection_of_collections )
00241 {
00242     Registry registry;
00243     import_test_types(registry);
00244     Container const& inside = Container::createContainer(registry, "/std/vector", *registry.get("int32_t"));
00245     Container const& container = Container::createContainer(registry, "/std/vector", inside);
00246 
00247     std::vector< std::vector<int32_t> > v;
00248     v.resize(10);
00249     for (int i = 0; i < 10; ++i)
00250     {
00251         v[i].resize(10);
00252         for (int j = 0; j < 10; ++j)
00253             v[i][j] = i * 100 + j;
00254     }
00255     std::vector<int32_t> new_element;
00256     new_element.push_back(1000);
00257     v.insert(v.begin() + 5, new_element);
00258 
00259     BOOST_REQUIRE(container.erase(&v, Value(&new_element, inside)));
00260 
00261     BOOST_REQUIRE_EQUAL(10, v.size());
00262 
00263     for (int i = 0; i < 10; ++i)
00264     {
00265         BOOST_REQUIRE_EQUAL(10, v[i].size());
00266         for (int j = 0; j < 10; ++j)
00267             BOOST_REQUIRE_EQUAL(i * 100 + j, v[i][j]);
00268     }
00269 }
00270 
00271 BOOST_AUTO_TEST_CASE( test_copy_collection_of_collections )
00272 {
00273     Registry registry;
00274     import_test_types(registry);
00275     Container const& inside = Container::createContainer(registry, "/std/vector", *registry.get("int32_t"));
00276     Container const& container = Container::createContainer(registry, "/std/vector", inside);
00277 
00278     std::vector< std::vector<int32_t> > v;
00279     v.resize(10);
00280     for (int i = 0; i < 10; ++i)
00281     {
00282         v[i].resize(10);
00283         for (int j = 0; j < 10; ++j)
00284             v[i][j] = i * 100 + j;
00285     }
00286 
00287     std::vector< std::vector<int32_t> > copy;
00288     Typelib::copy(Value(&copy, container), Value(&v, container));
00289 
00290     for (int i = 0; i < 10; ++i)
00291     {
00292         BOOST_REQUIRE_EQUAL(10, v[i].size());
00293         for (int j = 0; j < 10; ++j)
00294             BOOST_REQUIRE_EQUAL(i * 100 + j, v[i][j]);
00295     }
00296 
00297     BOOST_REQUIRE( Typelib::compare(Value(&copy, container), Value(&v, container)) );
00298 }
00299 


typelib
Author(s): Sylvain Joyeux/sylvain.joyeux@m4x.org
autogenerated on Sat Jun 8 2019 18:49:22