Possibility to pass class method reference
authorRafał Długołęcki <rafal@dlugolecki.net.pl>
Mon, 8 Feb 2016 00:38:16 +0000 (01:38 +0100)
committerRafał Długołęcki <rafal@dlugolecki.net.pl>
Mon, 8 Feb 2016 00:38:16 +0000 (01:38 +0100)
25 files changed:
include/argument.h
include/callable.h
tests/Makefile.am
tests/argument/handles_boolean_value.cpp
tests/argument/handles_float_value.cpp
tests/argument/handles_int_value.cpp
tests/argument/handles_negative_float_value.cpp
tests/argument/handles_negative_int_value.cpp
tests/argument/handles_string_value.cpp
tests/callable/TestCallable.h
tests/callable/invokes_class_method.cpp [new file with mode: 0644]
tests/callable/invokes_provided_function.cpp
tests/callable/invokes_void_function.cpp
tests/multiValue/should_extract_arguments_by_separator.cpp
tests/multiValue/should_extract_options_by_separator.cpp
tests/option/handles_boolean_value.cpp
tests/option/handles_float_value.cpp
tests/option/handles_int_value.cpp
tests/option/handles_negative_float_value.cpp
tests/option/handles_negative_int_value.cpp
tests/option/handles_string_value.cpp
tests/option/handles_void_value.cpp
tests/option/should_match_exact_name.cpp
tests/option/should_throw_exception_on_missing_value.cpp
tests/required/should_be_required.cpp

index 81a7cd4186e8c4be1c755b74d42829ab7e0fb25b..2cd3c300f970a8d2e205de7685a6f10fd9ad241d 100644 (file)
@@ -4,6 +4,7 @@
 #include <string>
 #include <sstream>
 #include <iostream>
+#include <functional>
 
 #include "parameter.h"
 #include "callable.h"
@@ -35,6 +36,10 @@ namespace command {
             : Parameter(description), Callable<ParameterType>(function) {
         }
 
+        Argument(const std::string & description, std::function<void(ParameterType)> function)
+            : Parameter(description), Callable<ParameterType>(function) {
+        }
+
         /**
          *
          */
index 4ac1bd97635e43d8b9956b35857155e59ba0ec1e..f4d9e084cabe385dfcee6cfbfb0adcf87016e551 100644 (file)
@@ -2,6 +2,7 @@
 #define __COMMAND_CALLABLE_H
 
 #include <string>
+#include <functional>
 
 namespace command {
     /**
@@ -13,7 +14,8 @@ namespace command {
         /**
          * Function handling user Arguments
          */
-        void (*func)(ParameterType);
+//         void (*func)(ParameterType);
+        std::function<void(ParameterType)> func;
 
     public:
         /**
@@ -21,7 +23,11 @@ namespace command {
          *
          * @param function Function that will be invoked
          */
-        Callable(void (*function)(ParameterType))
+//         Callable(void (*function)(ParameterType))
+//             : func(function) {
+//         }
+
+        Callable(std::function<void(ParameterType)> function)
             : func(function) {
         }
 
@@ -48,7 +54,8 @@ namespace command {
         /**
          * Function handling user Arguments
          */
-        void (*func)(void);
+//         void (*func)(void);
+        std::function<void(void)> func;
 
     public:
         /**
@@ -56,9 +63,14 @@ namespace command {
          *
          * @param function Function that will be invoked
          */
-        Callable(void (*function)(void))
+//         Callable(void (*function)(void))
+//             : func(function) {
+//         }
+
+        Callable(std::function<void(void)> function)
             : func(function) {
         }
+
         virtual ~Callable() { }
 
     protected:
index 4df147ebef0950d67f77c59f3d228c9da83a8b89..e17e256c212f08c9e279284b4ac9574b4511dbf2 100644 (file)
@@ -4,6 +4,7 @@ TEST_PROGS = \
        descriptive/holds_data.test \
        callable/invokes_provided_function.test \
        callable/invokes_void_function.test \
+       callable/invokes_class_method.test \
        parameter/is_descriptive.test \
        parameter/should_be_non_required.test \
        argument/handles_string_value.test \
@@ -51,6 +52,7 @@ descriptive_holds_data_test_SOURCES  = descriptive/holds_data.cpp
 
 callable_invokes_provided_function_test_SOURCES  = callable/invokes_provided_function.cpp
 callable_invokes_void_function_test_SOURCES  = callable/invokes_void_function.cpp
+callable_invokes_class_method_test_SOURCES  = callable/invokes_class_method.cpp
 
 parameter_is_descriptive_test_SOURCES  = parameter/is_descriptive.cpp
 parameter_should_be_non_required_test_SOURCES = parameter/should_be_non_required.cpp
index b41106f6de9e2025ce4aba208f7706932a02c668..5fb944e4546e0947ec13b3cdb319972f25ee97d4 100644 (file)
@@ -12,12 +12,12 @@ typedef bool ArgumentType;
 
 ArgumentType test;
 
-void function(ArgumentType value) {
+void _function(ArgumentType value) {
     test = value;
 }
 
 int main() {
-    Argument<ArgumentType> argument("Argument as boolean", function);
+    Argument<ArgumentType> argument("Argument as boolean", _function);
 
     if (argument.understand(FALSE)) {
         argument.handle();
@@ -31,7 +31,7 @@ int main() {
         cout << "Argument class handles boolean (FALSE) values\n";
     }
 
-    Argument<ArgumentType> argument2("Argument as boolean", function);
+    Argument<ArgumentType> argument2("Argument as boolean", _function);
     if (argument2.understand(TRUE)) {
         argument2.handle();
     }
index 9e53dc8d5b276f2d1cd9c11836ecab632f5a1492..f757a84f1e7c20e63a2b6261654c8fd3798bdcd9 100644 (file)
@@ -11,12 +11,12 @@ typedef float ArgumentType;
 
 ArgumentType test;
 
-void function(ArgumentType value) {
+void _function(ArgumentType value) {
     test = value;
 }
 
 int main() {
-    Argument<ArgumentType> argument("Argument as float", function);
+    Argument<ArgumentType> argument("Argument as float", _function);
 
     if (argument.understand(VALUE)) {
         argument.handle();
index ffe130c83cd30549951f3ab306424d41bc65f800..4295286063ed4c9ef192c6b363a09040426cb835 100644 (file)
@@ -12,12 +12,12 @@ typedef int ArgumentType;
 
 ArgumentType test;
 
-void function(ArgumentType value) {
+void _function(ArgumentType value) {
     test = value;
 }
 
 int main() {
-    Argument<ArgumentType> argument("Argument as int", function);
+    Argument<ArgumentType> argument("Argument as int", _function);
 
     if (argument.understand(VALUE)) {
         argument.handle();
index 7c97467244bb8be08e306d5edf31570006df88d1..c9e1e8fdb307024e5ede19834cb7e0401f84e3ff 100644 (file)
@@ -11,12 +11,12 @@ typedef float ArgumentType;
 
 ArgumentType test;
 
-void function(ArgumentType value) {
+void _function(ArgumentType value) {
     test = value;
 }
 
 int main() {
-    Argument<ArgumentType> argument("Argument as negative float", function);
+    Argument<ArgumentType> argument("Argument as negative float", _function);
 
     if (argument.understand(VALUE)) {
         argument.handle();
index f9c222f9d80caa3f43ec85b3bd616b21c3c7e064..3116526f2c752f092ad15f5c67fa5277f1d62b9a 100644 (file)
@@ -11,12 +11,12 @@ typedef int ArgumentType;
 
 ArgumentType test;
 
-void function(ArgumentType value) {
+void _function(ArgumentType value) {
     test = value;
 }
 
 int main() {
-    Argument<ArgumentType> argument("Argument as negative int", function);
+    Argument<ArgumentType> argument("Argument as negative int", _function);
 
     if (argument.understand(VALUE)) {
         argument.handle();
index 38e6efa98c5d6044eed80c110a7ca617b6e872ed..6f7309ed84ba09c3524e08308503f04b38bcdf93 100644 (file)
@@ -12,12 +12,12 @@ typedef std::string ArgumentType;
 
 ArgumentType test;
 
-void function(ArgumentType value) {
+void _function(ArgumentType value) {
     test = value;
 }
 
 int main() {
-    Argument<ArgumentType> argument("Argument as string", function);
+    Argument<ArgumentType> argument("Argument as string", _function);
 
     if (argument.understand(VALUE)) {
         argument.handle();
index 7fea87045200dacf0823ed10989ed91158235ceb..a4185c52bde0bac6df2587dde4bc067142f58930 100644 (file)
@@ -9,6 +9,10 @@ public:
         : Callable<ArgumentType>(function) {
     }
 
+    TestCallable(std::function<void(ArgumentType)> function)
+        : Callable<ArgumentType>(function) {
+    }
+
     void callFunction(ArgumentType test) {
         this->call(test);
     }
@@ -21,6 +25,10 @@ public:
         : Callable<void>(function) {
     }
 
+    TestCallable(std::function<void(void)> function)
+        : Callable<void>(function) {
+    }
+
     void callFunction() {
         this->call();
     }
diff --git a/tests/callable/invokes_class_method.cpp b/tests/callable/invokes_class_method.cpp
new file mode 100644 (file)
index 0000000..3b0de6b
--- /dev/null
@@ -0,0 +1,35 @@
+#include <cstring>
+#include <iostream>
+
+#include <functional> // std::bind, _1
+
+#include "TestCallable.h"
+#include "callable.h"
+
+using namespace std;
+using namespace command;
+
+bool test = false;
+
+class Class {
+public:
+    void method(void) {
+        test = true;
+    };
+};
+
+int main() {
+    Class c;
+    TestCallable<void> callable(std::bind(&Class::method, &c));
+    callable.callFunction();
+
+    if (test == true) {
+        cout << "Callable class calls provided class member method\n";
+        return 0;
+    }
+
+    cout << "Callable class does not call provided  member method\n";
+
+    return 1;
+}
+
index 5defb08cb1d2a790bd38274ac1cf0e89099452ae..b722fbeb93120d010383817153d5a04643fb49e2 100644 (file)
@@ -9,12 +9,12 @@ using namespace command;
 
 bool test = false;
 
-void function(bool val) {
+void _function(bool val) {
     test = val;
 };
 
 int main() {
-    TestCallable<bool> callable(function);
+    TestCallable<bool> callable(_function);
     callable.callFunction(true);
 
     if (test == true) {
index f0e46714db67a178f2837b14a803efeed9397c7d..bf881d0f5b5d7e64a5e6fedafedeec552048fc4a 100644 (file)
@@ -9,12 +9,12 @@ using namespace command;
 
 bool test = false;
 
-void function(void) {
+void _function(void) {
     test = true;
 };
 
 int main() {
-    TestCallable<void> callable(function);
+    TestCallable<void> callable(_function);
     callable.callFunction();
 
     if (test == true) {
index 8b5e5e3f918a1a480bcb6c1c0ca49f1f3151adad..4b0c1ec84311e375efa8297b0642744732120f08 100644 (file)
@@ -13,13 +13,13 @@ typedef int ArgumentType;
 
 std::vector<ArgumentType> input;
 
-void function(ArgumentType value) {
+void _function(ArgumentType value) {
     input.push_back(value);
     cout << "Catched value: " << value << "\n";
 }
 
 int main() {
-    Parameter * argument = new MultiValue(",", new Argument<ArgumentType>("Argument as multiValue int", function));
+    Parameter * argument = new MultiValue(",", new Argument<ArgumentType>("Argument as multiValue int", _function));
 
     try {
         if (argument->understand(VALUE)) {
index 1f19354c8f15a09256fe68635eb1a6a766010589..dbbc38a7e5633172cceb21799283471dcfbd6bd6 100644 (file)
@@ -16,13 +16,13 @@ typedef int OptionType;
 
 std::vector<OptionType> input;
 
-void function(OptionType value) {
+void _function(OptionType value) {
     input.push_back(value);
     cout << "Catched value: " << value << "\n";
 }
 
 int main() {
-    Parameter * option = new MultiValue(",", new Option<OptionType>(NAME, "Option as multiValue int", function));
+    Parameter * option = new MultiValue(",", new Option<OptionType>(NAME, "Option as multiValue int", _function));
 
     try {
         if (option->understand(OPTION)) {
index 473a6b7047423cd259e80050c9f9cb0af98abfb1..7e3193aa069bfcf888292d67012c3dce9ea1dd5b 100644 (file)
@@ -16,12 +16,12 @@ typedef bool OptionType;
 
 OptionType test;
 
-void function(OptionType value) {
+void _function(OptionType value) {
     test = value;
 }
 
 int main() {
-    Option<OptionType> option(NAME, "Option with boolean value", function);
+    Option<OptionType> option(NAME, "Option with boolean value", _function);
 
     if (option.understand(OPTION1)) {
         option.handle();
@@ -35,7 +35,7 @@ int main() {
         cout << option.describe() << " handles " << FALSE << " values\n";
     }
 
-    Option<OptionType> option2(NAME, "Option with boolean value", function);
+    Option<OptionType> option2(NAME, "Option with boolean value", _function);
 
     if (option2.understand(OPTION2)) {
         option2.handle();
index 6bbc5ed700ae440e4b4a22ea525967de12bf9c3a..e04b622da08a1f0f1b4f07bb4f35f4a7a9889989 100644 (file)
@@ -15,12 +15,12 @@ typedef float OptionType;
 
 OptionType test;
 
-void function(OptionType value) {
+void _function(OptionType value) {
     test = value;
 }
 
 int main() {
-    Option<OptionType> option(NAME, "Option with float value", function);
+    Option<OptionType> option(NAME, "Option with float value", _function);
 
     if (option.understand(OPTION)) {
         option.handle();
index a6d9c46f51152b5d245817e999f4d75c00ecde1d..a386c26c28596a0833e5cb6134b39feb95430d0b 100644 (file)
@@ -15,12 +15,12 @@ typedef int OptionType;
 
 OptionType test;
 
-void function(OptionType value) {
+void _function(OptionType value) {
     test = value;
 }
 
 int main() {
-    Option<OptionType> option(NAME, "Option as int", function);
+    Option<OptionType> option(NAME, "Option as int", _function);
 
     if (option.understand(OPTION)) {
         option.handle();
index 02bc7e0d87e5f7712412cbfcc8c337e9c801be7e..6e031139e1d9238dce0c141f72f60d6a6474fc83 100644 (file)
@@ -15,12 +15,12 @@ typedef float OptionType;
 
 OptionType test;
 
-void function(OptionType value) {
+void _function(OptionType value) {
     test = value;
 }
 
 int main() {
-    Option<OptionType> option(NAME, "Option with negative float value", function);
+    Option<OptionType> option(NAME, "Option with negative float value", _function);
 
     if (option.understand(OPTION)) {
         option.handle();
index 816e8da0fa8933a2cd0fc2fd45d5d3f40d066c21..2e2ea821d50f7f60beb7b9d42ad3b0e82856fcb0 100644 (file)
@@ -15,12 +15,12 @@ typedef int OptionType;
 
 OptionType test;
 
-void function(OptionType value) {
+void _function(OptionType value) {
     test = value;
 }
 
 int main() {
-    Option<OptionType> option(NAME, "Option as negative int", function);
+    Option<OptionType> option(NAME, "Option as negative int", _function);
 
     if (option.understand(OPTION)) {
         option.handle();
index 7f9099d42e8936d6c9eec353579d168600d24e66..c318351b6bbec00eadf717f4df736d6872612548 100644 (file)
@@ -15,12 +15,12 @@ typedef std::string OptionType;
 
 OptionType test;
 
-void function(OptionType value) {
+void _function(OptionType value) {
     test = value;
 }
 
 int main() {
-    Option<OptionType> option(NAME, "Option with string value", function);
+    Option<OptionType> option(NAME, "Option with string value", _function);
 
     if (option.understand(OPTION)) {
         option.handle();
index b6528e3bbb1c0cd01ebc5202cbafcb09c4d5a93e..4157bc403104b971769ca504106fc6e78361b525 100644 (file)
@@ -11,12 +11,12 @@ typedef void OptionType;
 
 bool test = false;
 
-void function() {
+void _function() {
     test = true;
 }
 
 int main() {
-    Option<OptionType> option(NAME, "Option with void value", function);
+    Option<OptionType> option(NAME, "Option with void value", _function);
 
     if (option.understand(NAME)) {
         option.handle();
index 81f3778a25873c5a16e54cbc61b76f4afd2f4a47..b5580f162a3b2a99a9eced7a8a3e23db6191f1e2 100644 (file)
@@ -8,7 +8,7 @@
 using namespace std;
 using namespace command;
 
-void function(void) { }
+void _function(void) { }
 
 int main() {
     std::vector<std::string> badOptions;
@@ -18,7 +18,7 @@ int main() {
     badOptions.push_back("te");
     badOptions.push_back("t");
 
-    Option<void> option(NAME, "Option should match only exact name", function);
+    Option<void> option(NAME, "Option should match only exact name", _function);
     for (std::string bad : badOptions) {
         if (option.understand(bad)) {
             std::cout << option.describe() << " but '" << NAME << "' was matched as same to '" << bad << "'\n";
index f872ed12292e7ef1dc77b30d80d970d4586118ea..4b901fb648d50d343703a5e9438763861ad55145 100644 (file)
@@ -9,10 +9,10 @@
 using namespace std;
 using namespace command;
 
-void function(int) { }
+void _function(int) { }
 
 int main() {
-    Option<int> option(NAME, "Option should throw exception on missing value", function);
+    Option<int> option(NAME, "Option should throw exception on missing value", _function);
 
     try {
         if (option.understand(BAD_OPTION)) {
index b59db3d5a88f014e29bf4d747197868cd87b993e..ee57160437d941548ddde15e20814357a1edf8a1 100644 (file)
@@ -14,11 +14,11 @@ using namespace command;
 
 typedef int Type;
 
-void function(Type val) { }
+void _function(Type val) { }
 
 int main() {
-    Parameter * requiredOption = new Required(new Option<Type>(NAME, "Required Option", function));
-    Parameter * requiredArgument = new Required(new Argument<Type>("Required Argument", function));
+    Parameter * requiredOption = new Required(new Option<Type>(NAME, "Required Option", _function));
+    Parameter * requiredArgument = new Required(new Argument<Type>("Required Argument", _function));
 
     if (!requiredOption->isRequired()) {
         cout << requiredOption->describe() << " should be treated as required but it is not\n";