@@ -437,10 +437,22 @@ template <class Ty> struct initializer {
437
437
template <class Opt > void apply (Opt &O) const { O.setInitialValue (Init); }
438
438
};
439
439
440
+ template <class Ty > struct list_initializer {
441
+ ArrayRef<Ty> Inits;
442
+ list_initializer (ArrayRef<Ty> Vals) : Inits(Vals) {}
443
+
444
+ template <class Opt > void apply (Opt &O) const { O.setInitialValues (Inits); }
445
+ };
446
+
440
447
template <class Ty > initializer<Ty> init (const Ty &Val) {
441
448
return initializer<Ty>(Val);
442
449
}
443
450
451
+ template <class Ty >
452
+ list_initializer<Ty> list_init (ArrayRef<Ty> Vals) {
453
+ return list_initializer<Ty>(Vals);
454
+ }
455
+
444
456
// Allow the user to specify which external variable they want to store the
445
457
// results of the command line argument processing into, if they don't want to
446
458
// store it in the option itself.
@@ -1504,6 +1516,9 @@ extern template class opt<bool>;
1504
1516
//
1505
1517
template <class DataType , class StorageClass > class list_storage {
1506
1518
StorageClass *Location = nullptr ; // Where to store the object...
1519
+ std::vector<OptionValue<DataType>> Default =
1520
+ std::vector<OptionValue<DataType>>();
1521
+ bool DefaultAssigned = false ;
1507
1522
1508
1523
public:
1509
1524
list_storage () = default ;
@@ -1517,12 +1532,22 @@ template <class DataType, class StorageClass> class list_storage {
1517
1532
return false ;
1518
1533
}
1519
1534
1520
- template <class T > void addValue (const T &V) {
1535
+ template <class T > void addValue (const T &V, bool initial = false ) {
1521
1536
assert (Location != nullptr &&
1522
1537
" cl::location(...) not specified for a command "
1523
1538
" line option with external storage!" );
1524
1539
Location->push_back (V);
1540
+ if (initial)
1541
+ Default.push_back (V);
1542
+ }
1543
+
1544
+ const std::vector<OptionValue<DataType>> &getDefault () const {
1545
+ return Default;
1525
1546
}
1547
+
1548
+ void assignDefault () { DefaultAssigned = true ; }
1549
+ void overwriteDefault () { DefaultAssigned = false ; }
1550
+ bool isDefaultAssigned () { return DefaultAssigned; }
1526
1551
};
1527
1552
1528
1553
// Define how to hold a class type object, such as a string.
@@ -1535,6 +1560,8 @@ template <class DataType, class StorageClass> class list_storage {
1535
1560
//
1536
1561
template <class DataType > class list_storage <DataType, bool > {
1537
1562
std::vector<DataType> Storage;
1563
+ std::vector<OptionValue<DataType>> Default;
1564
+ bool DefaultAssigned = false ;
1538
1565
1539
1566
public:
1540
1567
using iterator = typename std::vector<DataType>::iterator;
@@ -1598,7 +1625,19 @@ template <class DataType> class list_storage<DataType, bool> {
1598
1625
std::vector<DataType> *operator &() { return &Storage; }
1599
1626
const std::vector<DataType> *operator &() const { return &Storage; }
1600
1627
1601
- template <class T > void addValue (const T &V) { Storage.push_back (V); }
1628
+ template <class T > void addValue (const T &V, bool initial = false ) {
1629
+ Storage.push_back (V);
1630
+ if (initial)
1631
+ Default.push_back (OptionValue<DataType>(V));
1632
+ }
1633
+
1634
+ const std::vector<OptionValue<DataType>> &getDefault () const {
1635
+ return Default;
1636
+ }
1637
+
1638
+ void assignDefault () { DefaultAssigned = true ; }
1639
+ void overwriteDefault () { DefaultAssigned = false ; }
1640
+ bool isDefaultAssigned () { return DefaultAssigned; }
1602
1641
};
1603
1642
1604
1643
// ===----------------------------------------------------------------------===//
@@ -1622,6 +1661,10 @@ class list : public Option, public list_storage<DataType, StorageClass> {
1622
1661
StringRef Arg) override {
1623
1662
typename ParserClass::parser_data_type Val =
1624
1663
typename ParserClass::parser_data_type ();
1664
+ if (list_storage<DataType, StorageClass>::isDefaultAssigned ()) {
1665
+ clear ();
1666
+ list_storage<DataType, StorageClass>::overwriteDefault ();
1667
+ }
1625
1668
if (Parser.parse (*this , ArgName, Arg, Val))
1626
1669
return true ; // Parse Error!
1627
1670
list_storage<DataType, StorageClass>::addValue (Val);
@@ -1647,6 +1690,8 @@ class list : public Option, public list_storage<DataType, StorageClass> {
1647
1690
void setDefault () override {
1648
1691
Positions.clear ();
1649
1692
list_storage<DataType, StorageClass>::clear ();
1693
+ for (auto &Val : list_storage<DataType, StorageClass>::getDefault ())
1694
+ list_storage<DataType, StorageClass>::addValue (Val.getValue ());
1650
1695
}
1651
1696
1652
1697
void done () {
@@ -1666,6 +1711,20 @@ class list : public Option, public list_storage<DataType, StorageClass> {
1666
1711
return Positions[optnum];
1667
1712
}
1668
1713
1714
+ void clear () {
1715
+ Positions.clear ();
1716
+ list_storage<DataType, StorageClass>::clear ();
1717
+ }
1718
+
1719
+ // setInitialValues - Used by the cl::list_init modifier...
1720
+ void setInitialValues (ArrayRef<DataType> Vs) {
1721
+ assert (!(list_storage<DataType, StorageClass>::isDefaultAssigned ()) &&
1722
+ " Cannot have two default values" );
1723
+ list_storage<DataType, StorageClass>::assignDefault ();
1724
+ for (auto &Val : Vs)
1725
+ list_storage<DataType, StorageClass>::addValue (Val, true );
1726
+ }
1727
+
1669
1728
void setNumAdditionalVals (unsigned n) { Option::setNumAdditionalVals (n); }
1670
1729
1671
1730
template <class ... Mods>
0 commit comments