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
00030
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
00045
00046
00047
00048
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
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(©, 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(©, container), Value(&v, container)) );
00301 }
00302