diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2016-12-06 15:54:07 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2016-12-06 15:54:07 +0200 |
commit | 8e258e150743f9d71a7bbd9f70af78a05d354456 (patch) | |
tree | a7da748a935e965bfe7de93eb2c9fd7192d4878e | |
parent | beffa27ce8038c8e6d30b90f95a9d55ff5068c08 (diff) |
Work around wrong static initialization order in VC
-rw-r--r-- | build2/parser.cxx | 24 | ||||
-rw-r--r-- | build2/variable | 22 | ||||
-rw-r--r-- | build2/variable.txx | 33 |
3 files changed, 55 insertions, 24 deletions
diff --git a/build2/parser.cxx b/build2/parser.cxx index 87ec8b1..c47cc8b 100644 --- a/build2/parser.cxx +++ b/build2/parser.cxx @@ -1520,18 +1520,20 @@ namespace build2 static const value_type* map_type (const string& n) { + auto ptr = [] (const value_type& vt) {return &vt;}; + return - n == "bool" ? &value_traits<bool>::value_type : - n == "uint64" ? &value_traits<uint64_t>::value_type : - n == "string" ? &value_traits<string>::value_type : - n == "path" ? &value_traits<path>::value_type : - n == "dir_path" ? &value_traits<dir_path>::value_type : - n == "abs_dir_path" ? &value_traits<abs_dir_path>::value_type : - n == "name" ? &value_traits<name>::value_type : - n == "strings" ? &value_traits<strings>::value_type : - n == "paths" ? &value_traits<paths>::value_type : - n == "dir_paths" ? &value_traits<dir_paths>::value_type : - n == "names" ? &value_traits<vector<name>>::value_type : + n == "bool" ? ptr (value_traits<bool>::value_type) : + n == "uint64" ? ptr (value_traits<uint64_t>::value_type) : + n == "string" ? ptr (value_traits<string>::value_type) : + n == "path" ? ptr (value_traits<path>::value_type) : + n == "dir_path" ? ptr (value_traits<dir_path>::value_type) : + n == "abs_dir_path" ? ptr (value_traits<abs_dir_path>::value_type) : + n == "name" ? ptr (value_traits<name>::value_type) : + n == "strings" ? ptr (value_traits<strings>::value_type) : + n == "paths" ? ptr (value_traits<paths>::value_type) : + n == "dir_paths" ? ptr (value_traits<dir_paths>::value_type) : + n == "names" ? ptr (value_traits<vector<name>>::value_type) : nullptr; } diff --git a/build2/variable b/build2/variable index 8fc1fb9..0480a6c 100644 --- a/build2/variable +++ b/build2/variable @@ -694,8 +694,15 @@ namespace build2 static void prepend (value&, vector<T>&&); static bool empty (const vector<T>& x) {return x.empty ();} - static const string type_name; - static const build2::value_type value_type; + // Make sure these are static-initialized together. Failed that VC will + // make sure it's done in the wrong order. + // + struct value_type_ex: build2::value_type + { + string type_name; + value_type_ex (value_type&&); + }; + static const value_type_ex value_type; }; // map<K, V> @@ -713,8 +720,15 @@ namespace build2 return append (v, move (x));} static bool empty (const map<K, V>& x) {return x.empty ();} - static const string type_name; - static const build2::value_type value_type; + // Make sure these are static-initialized together. Failed that VC will + // make sure it's done in the wrong order. + // + struct value_type_ex: build2::value_type + { + string type_name; + value_type_ex (value_type&&); + }; + static const value_type_ex value_type; }; // variable_pool diff --git a/build2/variable.txx b/build2/variable.txx index d566a04..8db2ea9 100644 --- a/build2/variable.txx +++ b/build2/variable.txx @@ -357,13 +357,20 @@ namespace build2 } template <typename T> - const string value_traits<vector<T>>::type_name = string ( - value_traits<T>::type_name) + 's'; + value_traits<vector<T>>::value_type_ex:: + value_type_ex (value_type&& v) + : value_type (move (v)) + { + type_name = value_traits<T>::type_name; + type_name += 's'; + name = type_name.c_str (); + } template <typename T> - const value_type value_traits<vector<T>>::value_type = // VC14 wants =. + const typename value_traits<vector<T>>::value_type_ex + value_traits<vector<T>>::value_type = build2::value_type // VC14 wants =. { - value_traits<vector<T>>::type_name.c_str (), + nullptr, // Patched above. sizeof (vector<T>), nullptr, // No base. &default_dtor<vector<T>>, @@ -516,14 +523,22 @@ namespace build2 } template <typename K, typename V> - const string value_traits<std::map<K, V>>::type_name = string ( - value_traits<K>::type_name) + '_' + - value_traits<V>::type_name + "_map"; + value_traits<std::map<K, V>>::value_type_ex:: + value_type_ex (value_type&& v) + : value_type (move (v)) + { + type_name = value_traits<K>::type_name; + type_name += '_'; + type_name += value_traits<V>::type_name; + type_name += "_map"; + name = type_name.c_str (); + } template <typename K, typename V> - const value_type value_traits<std::map<K, V>>::value_type = // VC14 wants =. + const typename value_traits<std::map<K, V>>::value_type_ex + value_traits<std::map<K, V>>::value_type = build2::value_type // VC14 wants = { - value_traits<map<K, V>>::type_name.c_str (), + nullptr, // Patched above. sizeof (map<K, V>), nullptr, // No base. &default_dtor<map<K, V>>, |