summaryrefslogtreecommitdiff
path: root/tools/minicargo/stringlist.h
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2018-01-07 22:32:42 +0800
committerJohn Hodge <tpg@ucc.asn.au>2018-01-07 22:32:42 +0800
commit7bb1db4145bee893513876fc4b7fe0628a5a38db (patch)
treedfeadfc114e566353a2a8e6c5abb0b488baefc52 /tools/minicargo/stringlist.h
parent7e25c57d060e63649fbdf1f4c5810acb83d0b52c (diff)
downloadmrust-7bb1db4145bee893513876fc4b7fe0628a5a38db.tar.gz
minicargo - Add --target option for (incomplete) cross-compilation
Diffstat (limited to 'tools/minicargo/stringlist.h')
-rw-r--r--tools/minicargo/stringlist.h132
1 files changed, 132 insertions, 0 deletions
diff --git a/tools/minicargo/stringlist.h b/tools/minicargo/stringlist.h
new file mode 100644
index 00000000..4381121b
--- /dev/null
+++ b/tools/minicargo/stringlist.h
@@ -0,0 +1,132 @@
+/*
+ * minicargo - MRustC-specific clone of `cargo`
+ * - By John Hodge (Mutabah)
+ *
+ * stringlist.h
+ * - Helper classes for storing strings for use as cosnt char**
+ *
+ * StringList - Vector of strings
+ * StringListKV - Key/Value map
+ */
+#pragma once
+
+#include <vector>
+#include <string>
+
+class StringList
+{
+ ::std::vector<::std::string> m_cached;
+ ::std::vector<const char*> m_strings;
+public:
+ StringList()
+ {
+ }
+ StringList(const StringList&) = delete;
+ StringList(StringList&&) = default;
+
+ const ::std::vector<const char*>& get_vec() const
+ {
+ return m_strings;
+ }
+
+ void push_back(::std::string s)
+ {
+ // If the cache list is about to move, update the pointers
+ if(m_cached.capacity() == m_cached.size())
+ {
+ // Make a bitmap of entries in `m_strings` that are pointers into `m_cached`
+ ::std::vector<bool> b;
+ b.reserve(m_strings.size());
+ size_t j = 0;
+ for(const auto* s : m_strings)
+ {
+ if(j == m_cached.size())
+ break;
+ if(s == m_cached[j].c_str())
+ {
+ j ++;
+ b.push_back(true);
+ }
+ else
+ {
+ b.push_back(false);
+ }
+ }
+
+ // Add the new one
+ m_cached.push_back(::std::move(s));
+ // Update pointers
+ j = 0;
+ for(size_t i = 0; i < b.size(); i ++)
+ {
+ if(b[i])
+ {
+ m_strings[i] = m_cached.at(j++).c_str();
+ }
+ }
+ }
+ else
+ {
+ m_cached.push_back(::std::move(s));
+ }
+ m_strings.push_back(m_cached.back().c_str());
+ }
+ void push_back(const char* s)
+ {
+ m_strings.push_back(s);
+ }
+};
+class StringListKV: private StringList
+{
+ ::std::vector<const char*> m_keys;
+public:
+ StringListKV()
+ {
+ }
+ StringListKV(StringListKV&& x):
+ StringList(::std::move(x)),
+ m_keys(::std::move(x.m_keys))
+ {
+ }
+
+ void push_back(const char* k, ::std::string v)
+ {
+ m_keys.push_back(k);
+ StringList::push_back(v);
+ }
+ void push_back(const char* k, const char* v)
+ {
+ m_keys.push_back(k);
+ StringList::push_back(v);
+ }
+
+ struct Iter {
+ const StringListKV& v;
+ size_t i;
+
+ void operator++() {
+ this->i++;
+ }
+ ::std::pair<const char*,const char*> operator*() {
+ return ::std::make_pair(this->v.m_keys[this->i], this->v.get_vec()[this->i]);
+ }
+ bool operator!=(const Iter& x) const {
+ return this->i != x.i;
+ }
+ };
+ Iter begin() const {
+ return Iter { *this, 0 };
+ }
+ Iter end() const {
+ return Iter { *this, m_keys.size() };
+ }
+
+ friend ::std::ostream& operator<<(::std::ostream& os, const StringListKV& x) {
+ os << "{ ";
+ for(auto kv : x)
+ os << kv.first << "=" << kv.second << " ";
+ os << "}";
+ return os;
+ }
+};
+