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


typelib
Author(s): Sylvain Joyeux/sylvain.joyeux@m4x.org
autogenerated on Thu Jan 2 2014 11:38:41