Merge lp:~cwilson/spud/pointers_to_incomplete_type into lp:spud

Proposed by Cian Wilson
Status: Merged
Merged at revision: 537
Proposed branch: lp:~cwilson/spud/pointers_to_incomplete_type
Merge into: lp:spud
Diff against target: 335 lines (+73/-68)
2 files modified
include/spud (+7/-7)
src/spud.cpp (+66/-61)
To merge this branch: bzr merge lp:~cwilson/spud/pointers_to_incomplete_type
Reviewer Review Type Date Requested Status
Stephan Kramer Approve
Review via email: mp+267956@code.launchpad.net

Description of the change

I've been trying to compile spud using clang on mac OSX 10.10 (Yosemite) and ran into a few problems. This branch fixes them...

1. The Option class depends on storing a std::deque of std::pairs of std::strings and Options. This involves instantiating a deque using an incomplete type (as you're passing an Option type to the pair and deque from within the definition of the Option type). The behaviour of this is apparently undefined - the stdlib implementation we've been using on ubuntu has been able to deal with it but the llvm/clang/mac implementation complains:
"error: field has incomplete type 'Spud::OptionManager::Option'"
To deal with this I've changed the deque to store pairs of strings and pointers to Options. I've therefore also changed the destructors to delete these pointers.

2. spud.cpp was segfaulting at line 1456 (in the new branch). This was because child had been left pointing to children.end(), a new child had then been pushed back onto children and it was assumed that child (pointing to children.end()) would now point at the new entry in children, which appears not to be true with this stdlib implementation. A small fix just updates child to point at the new final entry in the children deque.

I've manually merged these changes into fluidity:
https://github.com/FluidityProject/fluidity/tree/cianwilson/spudchanges
(note that I've only merged these changes on top of what appears to be an out of date spud in fluidity). This passes make test locally and is being run through the buildbot here:
http://buildbot.ese.ic.ac.uk:8080/waterfall?show=cianwilson/spudchanges

To post a comment you must log in.
Revision history for this message
Cian Wilson (cwilson) wrote :

Green (fluidity) buildbot.

Revision history for this message
Stephan Kramer (s-kramer) wrote :

I've read it through (learning some c++ on the way) and it looks like a sensible solution to the described problem. Tested as well as is feasible. So I'd say: good to go!

review: Approve
Revision history for this message
Cian Wilson (cwilson) wrote :

Thanks Stephan!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'include/spud'
--- include/spud 2011-07-28 13:17:39 +0000
+++ include/spud 2015-08-13 14:29:36 +0000
@@ -192,15 +192,15 @@
192192
193 /** Finds first element with this key.193 /** Finds first element with this key.
194 */194 */
195 std::deque< std::pair<std::string, Option> >::iterator find(const std::string& key);195 std::deque< std::pair<std::string, Option*> >::iterator find(const std::string& key);
196 std::deque< std::pair<std::string, Option> >::const_iterator find(const std::string& key) const;196 std::deque< std::pair<std::string, Option*> >::const_iterator find(const std::string& key) const;
197197
198 /** Finds next element with this key after current iterator.198 /** Finds next element with this key after current iterator.
199 */199 */
200 std::deque< std::pair<std::string, Option> >::iterator200 std::deque< std::pair<std::string, Option*> >::iterator
201 find_next(std::deque< std::pair<std::string, Option> >::iterator current, const std::string& key);201 find_next(std::deque< std::pair<std::string, Option*> >::iterator current, const std::string& key);
202 std::deque< std::pair<std::string, Option> >::const_iterator202 std::deque< std::pair<std::string, Option*> >::const_iterator
203 find_next(std::deque< std::pair<std::string, Option> >::const_iterator current, const std::string& key) const;203 find_next(std::deque< std::pair<std::string, Option*> >::const_iterator current, const std::string& key) const;
204204
205 /**205 /**
206 * Get the number of elements at the supplied key. Searches all206 * Get the number of elements at the supplied key. Searches all
@@ -393,7 +393,7 @@
393 std::string data_as_string() const;393 std::string data_as_string() const;
394394
395 std::string node_name;395 std::string node_name;
396 std::deque< std::pair<std::string, Option> > children;396 std::deque< std::pair<std::string, Option*> > children;
397397
398 int rank, shape[2];398 int rank, shape[2];
399 std::vector<double> data_double;399 std::vector<double> data_double;
400400
=== modified file 'src/spud.cpp'
--- src/spud.cpp 2011-07-28 14:48:25 +0000
+++ src/spud.cpp 2015-08-13 14:29:36 +0000
@@ -673,6 +673,10 @@
673 }673 }
674674
675 OptionManager::Option::~Option(){675 OptionManager::Option::~Option(){
676 for(deque< pair<string, Option*> >::iterator it=children.begin();it!=children.end();++it){
677 delete it->second;
678 }
679
676 return;680 return;
677 }681 }
678682
@@ -779,7 +783,7 @@
779783
780 const Option* descendant = get_child(name);784 const Option* descendant = get_child(name);
781 if(descendant != NULL){785 if(descendant != NULL){
782 for(deque< pair<string, Option> >::const_iterator it = descendant->children.begin();it != descendant->children.end();it++){786 for(deque< pair<string, Option*> >::const_iterator it = descendant->children.begin();it != descendant->children.end();it++){
783 kids.push_back(it->first);787 kids.push_back(it->first);
784 }788 }
785 }789 }
@@ -789,31 +793,31 @@
789793
790 size_t OptionManager::Option::count(const string& key) const{794 size_t OptionManager::Option::count(const string& key) const{
791 size_t cnt=0;795 size_t cnt=0;
792 for(deque< pair<string, Option> >::const_iterator it=children.begin();it!=children.end();++it){796 for(deque< pair<string, Option*> >::const_iterator it=children.begin();it!=children.end();++it){
793 if(it->first == key)797 if(it->first == key)
794 cnt++;798 cnt++;
795 }799 }
796 return cnt;800 return cnt;
797 }801 }
798802
799 deque< pair<string, OptionManager::Option> >::iterator OptionManager::Option::find(const string& key){803 deque< pair<string, OptionManager::Option*> >::iterator OptionManager::Option::find(const string& key){
800 for(deque< pair<string, Option> >::iterator it=children.begin();it!=children.end();++it){804 for(deque< pair<string, Option*> >::iterator it=children.begin();it!=children.end();++it){
801 if(it->first == key)805 if(it->first == key)
802 return it;806 return it;
803 }807 }
804 return children.end();808 return children.end();
805 }809 }
806810
807 deque< pair<string, OptionManager::Option> >::const_iterator OptionManager::Option::find(const string& key) const{811 deque< pair<string, OptionManager::Option*> >::const_iterator OptionManager::Option::find(const string& key) const{
808 for(deque< pair<string, Option> >::const_iterator it=children.begin();it!=children.end();++it){812 for(deque< pair<string, Option*> >::const_iterator it=children.begin();it!=children.end();++it){
809 if(it->first == key)813 if(it->first == key)
810 return it;814 return it;
811 }815 }
812 return children.end();816 return children.end();
813 }817 }
814818
815 deque< pair<string, OptionManager::Option> >::iterator OptionManager::Option::find_next(deque< pair<string, OptionManager::Option> >::iterator current, const string& key){819 deque< pair<string, OptionManager::Option*> >::iterator OptionManager::Option::find_next(deque< pair<string, OptionManager::Option*> >::iterator current, const string& key){
816 deque< pair<string, OptionManager::Option> >::iterator it = current;820 deque< pair<string, OptionManager::Option*> >::iterator it = current;
817 it++;821 it++;
818 for(;it!=children.end();++it){822 for(;it!=children.end();++it){
819 if(it->first == key)823 if(it->first == key)
@@ -822,8 +826,8 @@
822 return children.end();826 return children.end();
823 }827 }
824828
825 deque< pair<string, OptionManager::Option> >::const_iterator OptionManager::Option::find_next(deque< pair<string, OptionManager::Option> >::const_iterator current, const string& key) const{829 deque< pair<string, OptionManager::Option*> >::const_iterator OptionManager::Option::find_next(deque< pair<string, OptionManager::Option*> >::const_iterator current, const string& key) const{
826 deque< pair<string, Option> >::const_iterator it = current;830 deque< pair<string, Option*> >::const_iterator it = current;
827 it++;831 it++;
828 for(;it!=children.end();++it){832 for(;it!=children.end();++it){
829 if(it->first == key)833 if(it->first == key)
@@ -850,7 +854,7 @@
850 return NULL;854 return NULL;
851 }855 }
852856
853 deque< pair<string, Option> >::const_iterator it;857 deque< pair<string, Option*> >::const_iterator it;
854 if(count(name) == 0){858 if(count(name) == 0){
855 name += "::";859 name += "::";
856 int i = 0;860 int i = 0;
@@ -880,9 +884,9 @@
880 if(it == children.end()){884 if(it == children.end()){
881 return NULL;885 return NULL;
882 }else if(branch.empty()){886 }else if(branch.empty()){
883 return &(it->second);887 return it->second;
884 }else{888 }else{
885 return it->second.get_child(branch);889 return it->second->get_child(branch);
886 }890 }
887 }891 }
888892
@@ -920,20 +924,20 @@
920 }924 }
921925
922 int count = 0, i = 0;926 int count = 0, i = 0;
923 for(deque< pair<string, Option> >::const_iterator it = children.begin();it != children.end();it++){927 for(deque< pair<string, Option*> >::const_iterator it = children.begin();it != children.end();it++){
924 if(it->first.compare(0, name.size(), name) == 0 and (not match_whole or it->first.size() == name.size())){928 if(it->first.compare(0, name.size(), name) == 0 and (not match_whole or it->first.size() == name.size())){
925 if(index < 0){929 if(index < 0){
926 if(branch.empty()){930 if(branch.empty()){
927 count++;931 count++;
928 }else{932 }else{
929 count += it->second.option_count(branch);933 count += it->second->option_count(branch);
930 }934 }
931 }else{935 }else{
932 if(i == index){936 if(i == index){
933 if(branch.empty()){937 if(branch.empty()){
934 count++;938 count++;
935 }else{939 }else{
936 count += it->second.option_count(branch);940 count += it->second->option_count(branch);
937 }941 }
938 break;942 break;
939 }943 }
@@ -961,7 +965,7 @@
961 cout << "OptionType OptionManager::Option::get_option_type(void) const\n";965 cout << "OptionType OptionManager::Option::get_option_type(void) const\n";
962966
963 if(have_option("__value")){967 if(have_option("__value")){
964 return find("__value")->second.get_option_type();968 return find("__value")->second->get_option_type();
965 }969 }
966970
967 if(!data_double.empty()){971 if(!data_double.empty()){
@@ -980,7 +984,7 @@
980 cout << "size_t OptionManager::Option::get_option_rank(void) const\n";984 cout << "size_t OptionManager::Option::get_option_rank(void) const\n";
981985
982 if(have_option("__value")){986 if(have_option("__value")){
983 return find("__value")->second.get_option_rank();987 return find("__value")->second->get_option_rank();
984 }else{988 }else{
985 return rank;989 return rank;
986 }990 }
@@ -991,7 +995,7 @@
991 cout << "vector<int> OptionManager::Option::get_option_shape(void) const\n";995 cout << "vector<int> OptionManager::Option::get_option_shape(void) const\n";
992996
993 if(have_option("__value")){997 if(have_option("__value")){
994 return find("__value")->second.get_option_shape();998 return find("__value")->second->get_option_shape();
995 }else{999 }else{
996 vector<int> shape(2);1000 vector<int> shape(2);
997 shape[0] = this->shape[0];1001 shape[0] = this->shape[0];
@@ -1234,15 +1238,15 @@
1234 return SPUD_KEY_ERROR;1238 return SPUD_KEY_ERROR;
1235 }1239 }
12361240
1237 Option new_option1 = Option(*option1);1241 Option* new_option1 = new Option(*option1);
1238 new_option1.node_name = key2_name;1242 new_option1->node_name = key2_name;
1239 string new_node_name, name_attr;1243 string new_node_name, name_attr;
1240 new_option1.split_node_name(new_node_name, name_attr);1244 new_option1->split_node_name(new_node_name, name_attr);
1241 if(name_attr.size() == 0){1245 if(name_attr.size() == 0){
1242 option2_parent->children.push_back(pair<string, Option>(new_node_name, new_option1));1246 option2_parent->children.push_back(pair<string, Option*>(new_node_name, new_option1));
1243 }else{1247 }else{
1244 new_option1.set_attribute("name", name_attr);1248 new_option1->set_attribute("name", name_attr);
1245 option2_parent->children.push_back(pair<string, Option>(new_node_name + "::" + name_attr, new_option1));1249 option2_parent->children.push_back(pair<string, Option*>(new_node_name + "::" + name_attr, new_option1));
1246 }1250 }
1247 1251
1248 return SPUD_NO_ERROR;1252 return SPUD_NO_ERROR;
@@ -1272,15 +1276,15 @@
1272 return SPUD_KEY_ERROR;1276 return SPUD_KEY_ERROR;
1273 }1277 }
12741278
1275 Option new_option1 = Option(*option1);1279 Option* new_option1 = new Option(*option1);
1276 new_option1.node_name = key2_name;1280 new_option1->node_name = key2_name;
1277 string new_node_name, name_attr;1281 string new_node_name, name_attr;
1278 new_option1.split_node_name(new_node_name, name_attr);1282 new_option1->split_node_name(new_node_name, name_attr);
1279 if(name_attr.size() == 0){1283 if(name_attr.size() == 0){
1280 option2_parent->children.push_back(pair<string, Option>(new_node_name, new_option1));1284 option2_parent->children.push_back(pair<string, Option*>(new_node_name, new_option1));
1281 }else{1285 }else{
1282 new_option1.set_attribute("name", name_attr);1286 new_option1->set_attribute("name", name_attr);
1283 option2_parent->children.push_back(pair<string, Option>(new_node_name + "::" + name_attr, new_option1));1287 option2_parent->children.push_back(pair<string, Option*>(new_node_name + "::" + name_attr, new_option1));
1284 }1288 }
1285 1289
1286 delete_option(key1);1290 delete_option(key1);
@@ -1302,16 +1306,16 @@
1302 if(opt == NULL){1306 if(opt == NULL){
1303 return SPUD_KEY_ERROR;1307 return SPUD_KEY_ERROR;
1304 }else if(branch.empty()){1308 }else if(branch.empty()){
1305 deque< pair<string, Option> >::iterator iter = find(name);1309 deque< pair<string, Option*> >::iterator iter = find(name);
1306 while(iter!=children.end()){1310 while(iter!=children.end()){
1307 if(&iter->second == opt){1311 if(iter->second == opt){
1308 children.erase(iter);1312 children.erase(iter);
1309 return SPUD_NO_ERROR;1313 return SPUD_NO_ERROR;
1310 }1314 }
1311 iter = find_next(iter, name);1315 iter = find_next(iter, name);
1312 }1316 }
1313 for(iter = children.begin();iter != children.end();iter++){1317 for(iter = children.begin();iter != children.end();iter++){
1314 if(&iter->second == opt){1318 if(iter->second == opt){
1315 children.erase(iter);1319 children.erase(iter);
1316 return SPUD_NO_ERROR;1320 return SPUD_NO_ERROR;
1317 }1321 }
@@ -1361,8 +1365,8 @@
1361 cout << lprefix << "<value>: " << data_string;1365 cout << lprefix << "<value>: " << data_string;
1362 cout << endl;1366 cout << endl;
1363 }1367 }
1364 for(deque< pair<string, Option> >::const_iterator i = children.begin();i!=children.end();++i){1368 for(deque< pair<string, Option*> >::const_iterator i = children.begin();i!=children.end();++i){
1365 i->second.print(lprefix + " ");1369 i->second->print(lprefix + " ");
1366 }1370 }
1367 }1371 }
13681372
@@ -1399,7 +1403,7 @@
1399 return NULL;1403 return NULL;
1400 }1404 }
14011405
1402 deque< pair<string, Option> >::iterator child;1406 deque< pair<string, Option*> >::iterator child;
1403 if(count(name) == 0){1407 if(count(name) == 0){
1404 string name2 = name + "::";1408 string name2 = name + "::";
1405 int i = 0;1409 int i = 0;
@@ -1417,11 +1421,12 @@
1417 cerr << "SPUD WARNING: Creating __value child for non null element - deleting parent data" << endl;1421 cerr << "SPUD WARNING: Creating __value child for non null element - deleting parent data" << endl;
1418 set_option_type(SPUD_NONE);1422 set_option_type(SPUD_NONE);
1419 }1423 }
1420 children.push_back(pair<string, Option>(name, Option(name)));1424 children.push_back(pair<string, Option*>(name, new Option(name)));
1421 string new_node_name, name_attr;1425 string new_node_name, name_attr;
1422 children.rbegin()->second.split_node_name(new_node_name, name_attr);1426 child = children.end(); child--;
1427 child->second->split_node_name(new_node_name, name_attr);
1423 if(name_attr.size() > 0){1428 if(name_attr.size() > 0){
1424 children.rbegin()->second.set_attribute("name", name_attr);1429 child->second->set_attribute("name", name_attr);
1425 }1430 }
1426 is_attribute = false;1431 is_attribute = false;
1427 }1432 }
@@ -1438,7 +1443,7 @@
1438 child = find_next(child, name);1443 child = find_next(child, name);
1439 }1444 }
1440 if(child == children.end() and index == (int)i){1445 if(child == children.end() and index == (int)i){
1441 children.push_back(pair<string, Option>(name, Option(name)));1446 children.push_back(pair<string, Option*>(name, new Option(name)));
1442 child = children.end(); child--;1447 child = children.end(); child--;
1443 is_attribute = false;1448 is_attribute = false;
1444 }1449 }
@@ -1448,9 +1453,9 @@
1448 if(child == children.end()){1453 if(child == children.end()){
1449 return NULL;1454 return NULL;
1450 }else if(branch.empty()){1455 }else if(branch.empty()){
1451 return &child->second;1456 return child->second;
1452 }else{1457 }else{
1453 return child->second.create_child(branch);1458 return child->second->create_child(branch);
1454 }1459 }
1455 }1460 }
14561461
@@ -1700,15 +1705,15 @@
1700 data_ele->SetValue(data_as_string());1705 data_ele->SetValue(data_as_string());
1701 ele->LinkEndChild(data_ele);1706 ele->LinkEndChild(data_ele);
17021707
1703 for(deque< pair<string, Option> >::const_iterator iter = children.begin();iter != children.end();iter++){1708 for(deque< pair<string, Option*> >::const_iterator iter = children.begin();iter != children.end();iter++){
1704 if(iter->second.is_attribute){1709 if(iter->second->is_attribute){
1705 // Add attribute1710 // Add attribute
1706 ele->SetAttribute(iter->second.node_name, iter->second.data_as_string());1711 ele->SetAttribute(iter->second->node_name, iter->second->data_as_string());
1707 }else{1712 }else{
1708 TiXmlElement* child_ele = iter->second.to_element();1713 TiXmlElement* child_ele = iter->second->to_element();
1709 if(iter->second.node_name == "__value"){1714 if(iter->second->node_name == "__value"){
1710 // Detect data sub-element1715 // Detect data sub-element
1711 switch(iter->second.get_option_type()){1716 switch(iter->second->get_option_type()){
1712 case(SPUD_DOUBLE):1717 case(SPUD_DOUBLE):
1713 child_ele->SetValue("real_value");1718 child_ele->SetValue("real_value");
1714 break;1719 break;

Subscribers

People subscribed via source and target branches