aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-12-06 15:54:07 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-12-06 15:54:07 +0200
commit8e258e150743f9d71a7bbd9f70af78a05d354456 (patch)
treea7da748a935e965bfe7de93eb2c9fd7192d4878e
parentbeffa27ce8038c8e6d30b90f95a9d55ff5068c08 (diff)
Work around wrong static initialization order in VC
-rw-r--r--build2/parser.cxx24
-rw-r--r--build2/variable22
-rw-r--r--build2/variable.txx33
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>>,