Commit 2fae7e2cdf7486ab17cf754b3e51034722a4b57f

Authored by Henry Fredrick Schreiner
1 parent c10bece4

Adding bool flag

include/CLI.hpp
@@ -104,6 +104,16 @@ struct is_vector<std::vector<T, A> > { @@ -104,6 +104,16 @@ struct is_vector<std::vector<T, A> > {
104 static bool const value = true; 104 static bool const value = true;
105 }; 105 };
106 106
  107 +template <typename T>
  108 +struct is_bool {
  109 + static const bool value = false;
  110 +};
  111 +
  112 +template<>
  113 +struct is_bool<bool> {
  114 + static bool const value = true;
  115 +};
  116 +
107 namespace detail { 117 namespace detail {
108 // Based generally on https://rmf.io/cxx11/almost-static-if 118 // Based generally on https://rmf.io/cxx11/almost-static-if
109 /// Simple empty scoped class 119 /// Simple empty scoped class
@@ -748,10 +758,11 @@ public: @@ -748,10 +758,11 @@ public:
748 } 758 }
749 759
750 /// Add option for flag 760 /// Add option for flag
751 - template<typename T, enable_if_t<std::is_integral<T>::value, detail::enabler> = detail::dummy> 761 + template<typename T,
  762 + enable_if_t<std::is_integral<T>::value && !is_bool<T>::value, detail::enabler> = detail::dummy>
752 Option* add_flag( 763 Option* add_flag(
753 std::string name, ///< The name, short,long 764 std::string name, ///< The name, short,long
754 - T &count, ///< A varaible holding the count 765 + T &count, ///< A varaible holding the count
755 std::string discription="" ///< Discription string 766 std::string discription="" ///< Discription string
756 ) { 767 ) {
757 768
@@ -764,6 +775,25 @@ public: @@ -764,6 +775,25 @@ public:
764 return add_option(name, fun, discription, NOTHING); 775 return add_option(name, fun, discription, NOTHING);
765 } 776 }
766 777
  778 + /// Bool version only allows the flag once
  779 + template<typename T,
  780 + enable_if_t<is_bool<T>::value, detail::enabler> = detail::dummy>
  781 + Option* add_flag(
  782 + std::string name, ///< The name, short,long
  783 + T &count, ///< A varaible holding true if passed
  784 + std::string discription="" ///< Discription string
  785 + ) {
  786 +
  787 + count = false;
  788 + CLI::callback_t fun = [&count](CLI::results_t res){
  789 + count = true;
  790 + return res.size() == 1;
  791 + };
  792 +
  793 + return add_option(name, fun, discription, NOTHING);
  794 + }
  795 +
  796 +
767 /// Add set of options 797 /// Add set of options
768 template<typename T> 798 template<typename T>
769 Option* add_set( 799 Option* add_set(
tests/CLITest.cpp
@@ -141,6 +141,38 @@ TEST_F(TApp, LotsOfFlags) { @@ -141,6 +141,38 @@ TEST_F(TApp, LotsOfFlags) {
141 EXPECT_EQ(1, app.count("A")); 141 EXPECT_EQ(1, app.count("A"));
142 } 142 }
143 143
  144 +
  145 +TEST_F(TApp, BoolAndIntFlags) {
  146 +
  147 + bool bflag;
  148 + int iflag;
  149 + unsigned int uflag;
  150 +
  151 + app.add_flag("b", bflag);
  152 + app.add_flag("i", iflag);
  153 + app.add_flag("u", uflag);
  154 +
  155 + args = {"-b", "-i", "-u"};
  156 + EXPECT_NO_THROW(run());
  157 + EXPECT_TRUE(bflag);
  158 + EXPECT_EQ(1, iflag);
  159 + EXPECT_EQ((unsigned int) 1, uflag);
  160 +
  161 + app.reset();
  162 +
  163 + args = {"-b", "-b"};
  164 + EXPECT_THROW(run(), CLI::ParseError);
  165 +
  166 + app.reset();
  167 + bflag = false;
  168 +
  169 + args = {"-iiiuu"};
  170 + EXPECT_NO_THROW(run());
  171 + EXPECT_FALSE(bflag);
  172 + EXPECT_EQ(3, iflag);
  173 + EXPECT_EQ((unsigned int) 2, uflag);
  174 +}
  175 +
144 TEST_F(TApp, ShortOpts) { 176 TEST_F(TApp, ShortOpts) {
145 177
146 unsigned long long funnyint; 178 unsigned long long funnyint;