From d9f97d149fa4afe770129420619cad6e83d2789a Mon Sep 17 00:00:00 2001 From: Chris Bieneman Date: Thu, 28 May 2015 21:31:22 +0000 Subject: [PATCH 1/1] Re-landing "Refactoring cl::list_storage from "is a" to "has a" std::vector." Originally landed r238485 MSVC resolves identifiers differently from Clang and GCC, this resulted in build bot failures. This pach re-lands r238485 and fixes the build failures. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@238505 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Support/CommandLine.h | 65 +++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 10 deletions(-) diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h index bd1d1cb6dc9..324db6e9e84 100644 --- a/include/llvm/Support/CommandLine.h +++ b/include/llvm/Support/CommandLine.h @@ -1284,24 +1284,69 @@ public: } }; -// Define how to hold a class type object, such as a string. Since we can -// inherit from a class, we do so. This makes us exactly compatible with the -// object in all cases that it is used. +// Define how to hold a class type object, such as a string. +// Originally this code inherited from std::vector. In transitioning to a new +// API for command line options we should change this. The new implementation +// of this list_storage specialization implements the minimum subset of the +// std::vector API required for all the current clients. // -template -class list_storage : public std::vector { +// FIXME: Reduce this API to a more narrow subset of std::vector +// +template class list_storage { + std::vector Storage; + public: - template void addValue(const T &V) { - std::vector::push_back(V); + typedef typename std::vector::iterator iterator; + + iterator begin() { return Storage.begin(); } + iterator end() { return Storage.end(); } + + typedef typename std::vector::const_iterator const_iterator; + const_iterator begin() const { return Storage.begin(); } + const_iterator end() const { return Storage.end(); } + + typedef typename std::vector::size_type size_type; + size_type size() const { return Storage.size(); } + + bool empty() const { return Storage.empty(); } + + void push_back(const DataType &value) { Storage.push_back(value); } + void push_back(DataType &&value) { Storage.push_back(value); } + + typedef typename std::vector::reference reference; + typedef typename std::vector::const_reference const_reference; + reference operator[](size_type pos) { return Storage[pos]; } + const_reference operator[](size_type pos) const { return Storage[pos]; } + + iterator erase(const_iterator pos) { return Storage.erase(pos); } + iterator erase(const_iterator first, const_iterator last) { + return Storage.erase(first, last); + } + + iterator insert(const_iterator pos, const DataType &value) { + return Storage.insert(pos, value); } + iterator insert(const_iterator pos, DataType &&value) { + return Storage.insert(pos, value); + } + + reference front() { return Storage.front(); } + const_reference front() const { return Storage.front(); } + + operator std::vector&() { return Storage; } + operator ArrayRef() { return Storage; } + std::vector *operator&() { return &Storage; } + const std::vector *operator&() const { return &Storage; } + + template void addValue(const T &V) { Storage.push_back(V); } }; //===----------------------------------------------------------------------===// // list - A list of command line options. // -template > -class list : public Option, public list_storage { +class list : public Option, public list_storage { std::vector Positions; ParserClass Parser; @@ -1319,7 +1364,7 @@ class list : public Option, public list_storage { typename ParserClass::parser_data_type(); if (Parser.parse(*this, ArgName, Arg, Val)) return true; // Parse Error! - list_storage::addValue(Val); + list_storage::addValue(Val); setPosition(pos); Positions.push_back(pos); return false; -- 2.34.1