art: Refactor RuntimeOptions/ParsedOptions

Refactor the RuntimeOptions to be a
type-safe map (VariantMap, see runtime_options.h) and the ParsedOptions
to delegate the parsing to CmdlineParser (see cmdline/cmdline_parser.h).

This is the start of a command line parsing refactor, and may include
more in the future (dex2oat, patchoat, etc).

For more details of the command line parsing generator usage see cmdline/README.md

Change-Id: Ic67c6bca5e1f33bf2ec60e2e3ff8c366bab91563
diff --git a/runtime/base/variant_map.h b/runtime/base/variant_map.h
new file mode 100644
index 0000000..cf7977e
--- /dev/null
+++ b/runtime/base/variant_map.h
@@ -0,0 +1,453 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_RUNTIME_BASE_VARIANT_MAP_H_
+#define ART_RUNTIME_BASE_VARIANT_MAP_H_
+
+#include <memory.h>
+#include <map>
+#include <utility>
+
+namespace art {
+
+//
+// A variant map is a heterogenous, type safe key->value map. It allows
+// for multiple different value types to be stored dynamically in the same map.
+//
+// It provides the following interface in a nutshell:
+//
+// struct VariantMap {
+//   template <typename TValue>
+//   TValue* Get(Key<T> key);  // nullptr if the value was never set, otherwise the value.
+//
+//   template <typename TValue>
+//   void Set(Key<T> key, TValue value);
+// };
+//
+// Since the key is strongly typed at compile-time, it is impossible to accidentally
+// read/write a value with a different type than the key at either compile-time or run-time.
+//
+// Do not use VariantMap/VariantMapKey directly. Instead subclass each of them and use
+// the subclass, for example:
+//
+// template <typename TValue>
+// struct FruitMapKey : VariantMapKey<TValue> {
+//   FruitMapKey() {}
+// };
+//
+// struct FruitMap : VariantMap<FruitMap, FruitMapKey> {
+//   // This 'using' line is necessary to inherit the variadic constructor.
+//   using VariantMap<FruitMap, FruitMapKey>::VariantMap;
+//
+//   // Make the next '4' usages of Key slightly shorter to type.
+//   template <typename TValue>
+//   using Key = FruitMapKey<TValue>;
+//
+//   static const Key<int> Apple;
+//   static const Key<double> Orange;
+//   static const Key<std::string> Banana;
+// };
+//
+// const FruitMap::Key<int> FruitMap::Apple;
+// const FruitMap::Key<double> FruitMap::Orange;
+// const FruitMap::Key<std::string> Banana;
+//
+// See variant_map_test.cc for more examples.
+//
+
+// Implementation details for VariantMap.
+namespace detail {
+  // Allocate a unique counter value each time it's called.
+  struct VariantMapKeyCounterAllocator {
+    static size_t AllocateCounter() {
+      static size_t counter = 0;
+      counter++;
+
+      return counter;
+    }
+  };
+
+  // Type-erased version of VariantMapKey<T>
+  struct VariantMapKeyRaw {
+    // TODO: this may need to call a virtual function to support string comparisons
+    bool operator<(const VariantMapKeyRaw& other) const {
+      return key_counter_ < other.key_counter_;
+    }
+
+    // The following functions need to be virtual since we don't know the compile-time type anymore:
+
+    // Clone the key, creating a copy of the contents.
+    virtual VariantMapKeyRaw* Clone() const = 0;
+
+    // Delete a value whose runtime type is that of the non-erased key's TValue.
+    virtual void ValueDelete(void* value) const = 0;
+
+    // Clone a value whose runtime type is that of the non-erased key's TValue.
+    virtual void* ValueClone(void* value) const = 0;
+
+    // Compare one key to another (same as operator<).
+    virtual bool Compare(const VariantMapKeyRaw* other) const {
+      if (other == nullptr) {
+        return false;
+      }
+      return key_counter_ < other->key_counter_;
+    }
+
+    virtual ~VariantMapKeyRaw() {}
+
+   protected:
+    VariantMapKeyRaw()
+        : key_counter_(VariantMapKeyCounterAllocator::AllocateCounter()) {}
+    // explicit VariantMapKeyRaw(size_t counter)
+    //     : key_counter_(counter) {}
+
+    size_t GetCounter() const {
+      return key_counter_;
+    }
+
+   protected:
+    // Avoid the object slicing problem; use Clone() instead.
+    VariantMapKeyRaw(const VariantMapKeyRaw& other) = default;
+    VariantMapKeyRaw(VariantMapKeyRaw&& other) = default;
+
+   private:
+    size_t key_counter_;  // Runtime type ID. Unique each time a new type is reified.
+  };
+}  // namespace detail
+
+// The base type for keys used by the VariantMap. Users must subclass this type.
+template <typename TValue>
+struct VariantMapKey : detail::VariantMapKeyRaw {
+  // Instantiate a default value for this key. If an explicit default value was provided
+  // then that is used. Otherwise, the default value for the type TValue{} is returned.
+  TValue CreateDefaultValue() const {
+    if (default_value_ == nullptr) {
+      return TValue{};  // NOLINT [readability/braces] [4]
+    } else {
+      return TValue(*default_value_);
+    }
+  }
+
+ protected:
+  // explicit VariantMapKey(size_t counter) : detail::VariantMapKeyRaw(counter) {}
+  explicit VariantMapKey(const TValue& default_value)
+    : default_value_(std::make_shared<TValue>(default_value)) {}
+  explicit VariantMapKey(TValue&& default_value)
+    : default_value_(std::make_shared<TValue>(default_value)) {}
+  VariantMapKey() {}
+  virtual ~VariantMapKey() {}
+
+ private:
+  virtual VariantMapKeyRaw* Clone() const {
+    return new VariantMapKey<TValue>(*this);
+  }
+
+  virtual void* ValueClone(void* value) const {
+    if (value == nullptr) {
+      return nullptr;
+    }
+
+    TValue* strong_value = reinterpret_cast<TValue*>(value);
+    return new TValue(*strong_value);
+  }
+
+  virtual void ValueDelete(void* value) const {
+    if (value == nullptr) {
+      return;
+    }
+
+    // Smartly invoke the proper delete/delete[]/etc
+    const std::default_delete<TValue> deleter = std::default_delete<TValue>();
+    deleter(reinterpret_cast<TValue*>(value));
+  }
+
+  VariantMapKey(const VariantMapKey& other) = default;
+  VariantMapKey(VariantMapKey&& other) = default;
+
+  template <typename Base, template <typename TV> class TKey> friend struct VariantMap;
+
+  // Store a prototype of the key's default value, for usage with VariantMap::GetOrDefault
+  std::shared_ptr<TValue> default_value_;
+};
+
+// Implementation details for a stringified VariantMapStringKey.
+namespace detail {
+  struct VariantMapStringKeyRegistry {
+    // TODO
+  };
+}  // namespace detail
+
+// Alternative base type for all keys used by VariantMap, supports runtime strings as the name.
+template <typename TValue>
+struct VariantMapStringKey : VariantMapKey<TValue> {
+  explicit VariantMapStringKey(const char* name)
+      :   // VariantMapKey(/*std::hash<std::string>()(name)*/),
+        name_(name) {
+  }
+
+ private:
+  const char* name_;
+};
+
+// A variant map allows type-safe heteregeneous key->value mappings.
+// All possible key types must be specified at compile-time. Values may be added/removed
+// at runtime.
+template <typename Base, template <typename TV> class TKey>
+struct VariantMap {
+  // Allow users of this static interface to use the key type.
+  template <typename TValue>
+  using Key = TKey<TValue>;
+
+  // Look up the value from the key. The pointer becomes invalid if this key is overwritten/removed.
+  // A null value is returned only when the key does not exist in this map.
+  template <typename TValue>
+  const TValue* Get(const TKey<TValue>& key) const {
+    return GetValuePtr(key);
+  }
+
+  // Look up the value from the key. The pointer becomes invalid if this key is overwritten/removed.
+  // A null value is returned only when the key does not exist in this map.
+  template <typename TValue>
+  TValue* Get(const TKey<TValue>& key) {
+    return GetValuePtr(key);
+  }
+
+  // Lookup the value from the key. If it was not set in the map, return the default value.
+  // The default value is either the key's default, or TValue{} if the key doesn't have a default.
+  template <typename TValue>
+  TValue GetOrDefault(const TKey<TValue>& key) const {
+    auto* ptr = Get(key);
+    return (ptr == nullptr) ? key.CreateDefaultValue() : *ptr;
+  }
+
+ private:
+  // TODO: move to detail, or make it more generic like a ScopeGuard(function)
+  template <typename TValue>
+  struct ScopedRemove {
+    ScopedRemove(VariantMap& map, const TKey<TValue>& key) : map_(map), key_(key) {}
+    ~ScopedRemove() {
+      map_.Remove(key_);
+    }
+
+    VariantMap& map_;
+    const TKey<TValue>& key_;
+  };
+
+ public:
+  // Release the value from the key. If it was not set in the map, returns the default value.
+  // If the key was set, it is removed as a side effect.
+  template <typename TValue>
+  TValue ReleaseOrDefault(const TKey<TValue>& key) {
+    ScopedRemove<TValue> remove_on_return(*this, key);
+
+    TValue* ptr = Get(key);
+    if (ptr != nullptr) {
+      return std::move(*ptr);
+    } else {
+      TValue default_value = key.CreateDefaultValue();
+      return std::move(default_value);
+    }
+  }
+
+  // See if a value is stored for this key.
+  template <typename TValue>
+  bool Exists(const TKey<TValue>& key) const {
+    return GetKeyValueIterator(key) != storage_map_.end();
+  }
+
+  // Set a value for a given key, overwriting the previous value if any.
+  template <typename TValue>
+  void Set(const TKey<TValue>& key, const TValue& value) {
+    Remove(key);
+    storage_map_.insert({{key.Clone(), new TValue(value)}});
+  }
+
+  // Set a value for a given key, only if there was no previous value before.
+  // Returns true if the value was set, false if a previous value existed.
+  template <typename TValue>
+  bool SetIfMissing(const TKey<TValue>& key, const TValue& value) {
+    TValue* ptr = Get(key);
+    if (ptr == nullptr) {
+      Set(key, value);
+      return true;
+    }
+    return false;
+  }
+
+  // Remove the value for a given key, or a no-op if there was no previously set value.
+  template <typename TValue>
+  void Remove(const TKey<TValue>& key) {
+    StaticAssertKeyType<TValue>();
+
+    auto&& it = GetKeyValueIterator(key);
+    if (it != storage_map_.end()) {
+      key.ValueDelete(it->second);
+      delete it->first;
+      storage_map_.erase(it);
+    }
+  }
+
+  // Remove all key/value pairs.
+  void Clear() {
+    DeleteStoredValues();
+    storage_map_.clear();
+  }
+
+  // How many key/value pairs are stored in this map.
+  size_t Size() const {
+    return storage_map_.size();
+  }
+
+  // Construct an empty map.
+  explicit VariantMap() {}
+
+  template <typename ... TKeyValue>
+  explicit VariantMap(const TKeyValue& ... key_value_list) {
+    static_assert(sizeof...(TKeyValue) % 2 == 0, "Must be an even number of key/value elements");
+    InitializeParameters(key_value_list...);
+  }
+
+  // Create a new map from an existing map, copying all the key/value pairs.
+  VariantMap(const VariantMap& other) {
+    operator=(other);
+  }
+
+  // Copy the key/value pairs from the other map into this one. Existing key/values are cleared.
+  VariantMap& operator=(const VariantMap& other) {
+    if (this == &other) {
+      return *this;
+    }
+
+    Clear();
+
+    for (auto&& kv_pair : other.storage_map_) {
+      const detail::VariantMapKeyRaw* raw_key_other = kv_pair.first;
+      void* value = kv_pair.second;
+
+      detail::VariantMapKeyRaw* cloned_raw_key = raw_key_other->Clone();
+      void* cloned_value = raw_key_other->ValueClone(value);
+
+      storage_map_.insert({{ cloned_raw_key, cloned_value }});
+    }
+
+    return *this;
+  }
+
+  // Create a new map by moving an existing map into this one. The other map becomes empty.
+  VariantMap(VariantMap&& other) {
+    operator=(std::forward<VariantMap>(other));
+  }
+
+  // Move the existing map's key/value pairs into this one. The other map becomes empty.
+  VariantMap& operator=(VariantMap&& other) {
+    if (this != &other) {
+      Clear();
+      storage_map_.swap(other.storage_map_);
+      other.storage_map_.clear();
+    }
+    return *this;
+  }
+
+  ~VariantMap() {
+    DeleteStoredValues();
+  }
+
+ private:
+  void InitializeParameters() {}
+
+  template <typename TK, typename TValue, typename ... Rest>
+  void InitializeParameters(const TK& key, const TValue& value, const Rest& ... rest) {
+    static_assert(
+        std::is_same<TK, TKey<TValue>>::value, "The 0th/2nd/4th/etc parameters must be a key");
+
+    const TKey<TValue>& key_refined = key;
+
+    Set(key_refined, value);
+    InitializeParameters(rest...);
+  }
+
+  // Custom key comparator for std::map, needed since we are storing raw pointers as the keys.
+  struct KeyComparator {
+    bool operator()(const detail::VariantMapKeyRaw* lhs,
+                    const detail::VariantMapKeyRaw* rhs) const {
+      if (lhs == nullptr) {
+        return lhs != rhs;
+      }
+
+      return lhs->Compare(rhs);
+    }
+  };
+
+  // Map of key pointers to value pointers. Pointers are never null.
+  using StorageMap = std::map<const detail::VariantMapKeyRaw*, void*, KeyComparator>;
+
+  template <typename TValue>
+  typename StorageMap::iterator GetKeyValueIterator(const TKey<TValue>& key) {
+    StaticAssertKeyType<TValue>();
+
+    const TKey<TValue>* key_ptr = &key;
+    const detail::VariantMapKeyRaw* raw_ptr = key_ptr;
+    return storage_map_.find(raw_ptr);
+  }
+
+  template <typename TValue>
+  typename StorageMap::const_iterator GetKeyValueIterator(const TKey<TValue>& key) const {
+    StaticAssertKeyType<TValue>();
+
+    const TKey<TValue>* key_ptr = &key;
+    const detail::VariantMapKeyRaw* raw_ptr = key_ptr;
+    return storage_map_.find(raw_ptr);
+  }
+
+  template <typename TValue>
+  TValue* GetValuePtr(const TKey<TValue>& key) {
+    return const_cast<TValue*>(GetValueConstPtr(key));
+  }
+
+  template <typename TValue>
+  const TValue* GetValuePtr(const TKey<TValue>& key) const {
+    return GetValueConstPtr(key);
+  }
+
+  template <typename TValue>
+  const TValue* GetValueConstPtr(const TKey<TValue>& key) const {
+    auto&& it = GetKeyValueIterator(key);
+    if (it == storage_map_.end()) {
+      return nullptr;
+    }
+
+    return reinterpret_cast<const TValue*>(it->second);
+  }
+
+  template <typename TValue>
+  static void StaticAssertKeyType() {
+    static_assert(std::is_base_of<VariantMapKey<TValue>, TKey<TValue>>::value,
+                  "The provided key type (TKey) must be a subclass of VariantMapKey");
+  }
+
+  void DeleteStoredValues() {
+    for (auto&& kv_pair : storage_map_) {
+      kv_pair.first->ValueDelete(kv_pair.second);
+      delete kv_pair.first;
+    }
+  }
+
+  StorageMap storage_map_;
+};
+
+}  // namespace art
+
+#endif  // ART_RUNTIME_BASE_VARIANT_MAP_H_