Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature functional tooling start #74

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ AddHeaderFile("ContainerTools.h")
AddHeaderFile("CountedPtr.h")
AddHeaderFile("CommandLine.h")
AddHeaderFile("FlatMap.h")
AddHeaderFile("FunctionalTools.h")
AddHeaderFile("Introspection.h")
AddHeaderFile("ManagedArray.h")
AddHeaderFile("MurmurHash.h")
Expand All @@ -168,6 +169,7 @@ ShowList("Header Files:" "\t" "${FoundationHeaderFiles}")
AddSourceFile("Base64.cpp")
AddSourceFile("BinaryBuffer.cpp")
AddSourceFile("CommandLine.cpp")
AddSourceFile("FunctionalTools.cpp")
AddSourceFile("MurmurHash.cpp")
AddSourceFile("StreamLogging.cpp")
AddSourceFile("StringTools.cpp")
Expand All @@ -191,6 +193,7 @@ AddTestFile("CountedPtrTests.h")
AddTestFile("CommandLineTests.h")
AddTestFile("ExceptionTests.h")
AddTestFile("FlatMapTests.h")
AddTestFile("FunctionalToolsTests.h")
AddTestFile("IntrospectionTests.h")
AddTestFile("ManagedArrayTests.h")
AddTestFile("ManagedArraySequenceTests.h")
Expand Down
30 changes: 21 additions & 9 deletions include/CommandLine.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ const char ArgToken = '-';
/// @param ArgCount The count of arguments as given to main.
/// @param Arguments The "Argument Vector" as given to main.
/// @return An ArgVector with a 1 to 1 conversion of the inputs without opinions in parsing or tokenizing.
ArgVector MEZZ_LIB VectorizeArgs(int ArgCount, char** Arguments);
ArgVector MEZZ_LIB VectorizeArgs(int ArgCount, char** Arguments);

/// @brief An opinionated way to split grouped single letter args into multiple short arguments
/// @param DirtyArg A single arg prepended with '-' that should be split.
Expand All @@ -88,34 +88,50 @@ ArgMap MEZZ_LIB MapArgumentParameters(const ArgVector& DirtyArgs);

/// @brief A collection of arguments and possible associated flags.
/// @details This is a simple container for storing command line arguments after parsing them in an opinionated but
/// common way.
/// common way. The opinions lean towards the common features that GNU style arguments but do not conform exactly.
/// Single character options are prefixed by a single '-' and have a corresponding long option prefixed with '--'.
/// Either the short or long form can accept any amount of arguments with no '-'s at the beginning. All of this will
/// be stored in a one const data structure that can be referred to easily later.
/// @n @n
/// This accepts the Argument Count (commonly argc) and Argument Vector/Values(argv) in the constructor as they are
/// passed into main.
///
/// This accepts the Argument Count (commonly argc) and Argument Vector/Values (often argv) in the constructor as they
/// are passed into main. Here is one idealized example:
/// @code{.cpp}
/// int main(int ArgC, char** ArgV)
/// {
/// const CommandLineArguments Parsed(ArgC, ArgV);
/// @endcode
///
/// And Another that is actually an example from our Mezzy Tool:
/// @code{.cpp}
/// Mezzanine::ExitCode main(int ArgCount, char** Arguments)
/// {
/// // Parse command line arguments
/// Mezzanine::CommandLineArguments ParsedArgs(ArgCount, Arguments);
/// @endcode
///
/// After this the instannce of CommandLineArguments has only readable members, every member is const and nothing is
/// mutable. This is to insure that accidents cause compilation errors and allows confidence that use of this that
/// compile are likely to be correct (or at least only wrong because of runtime logic errors like indexing errors).
/// @n @n
///
/// This tries to look a little like typical GNU command line arguments. This handles "long"
/// arguments that start with "--" like "--all" and this handles "short" arguments that start with "-" like "-a and
/// combined short forms like "-rf".
/// @n @n
///
/// This also handles arguments without a "-" prefix by presuming they are parameters for previous arguments. Many
/// arguments need additional information to specify some behavior. Consider a potential zip command, it might accept a
/// "--file" flag to indicate the name of the zip file to work with. This could parse this syntax like this
/// "myZipCommand --file fileToWork.zip".
/// @n @n
///
/// This makes no further guarantees about preserving the order arguments are passed in. For example "-wtf" is the same
/// as "-tfw" are treated the same as long as there are no trailing parameters for those arguments.
/// @n @n
/// This converts all arguments to keys in a map with a value of a vector of their parameters. Consider this command:
/// @code
/// foo.exe -s
/// $ foo.exe -s
/// @endcode
///
/// This would store "foo.exe" in the data member ExecutableCommand and turns the arg into a dictionary with one key,
Expand All @@ -124,10 +140,6 @@ ArgMap MEZZ_LIB MapArgumentParameters(const ArgVector& DirtyArgs);
/// { {"-s", {} }
/// @endcode
///
/// The following examples have the same executable command and but would make slightly different data structures and
/// are illustrated as possible initializer lists:
/// @n @n
///
/// Short arguments are broken up, and long arguments are not. Short arguments have one ArgToken ("-"), long have two
/// ArgTokens. Consider this example:
/// @code
Expand Down
48 changes: 48 additions & 0 deletions include/ContainerTools.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,51 @@ namespace ContainerDetect {
constexpr Boole HasClear()
{ return HasClear_t<Class>::value; }

/// @brief Convenience type for push_back function detection.
/// @tparam Class The class to test.
template<typename Class>
using PushBackValueFunct_t = decltype(std::declval<Class&>().push_back(std::declval<typename Class::value_type>()));
/// @brief Type for is_detected that tests for the existence of push_back on a class.
/// @tparam Class The class that will be checked for the presence of a push_back function.
template<typename Class>
using PushBackValue_t = std::is_detected<PushBackValueFunct_t,Class>;
/// @brief Convenience function for the value of a HasPushBackValue check.
/// @tparam Class The class that will be checked for the presence of a "push_back(class::value_type)" function.
/// @return Returns true if the provided type has a "push_back()" member function that accepts a value, false otherwise.
template<typename Class>
constexpr Boole HasPushBackValue()
{ return PushBackValue_t<Class>::value; }

/// @brief Convenience type for insert function detection.
/// @tparam Class The class to test.
template<typename Class>
using InsertValueFunct_t = decltype(std::declval<Class&>().insert(std::declval<typename Class::value_type>()));
/// @brief Type for is_detected that tests for the existence of insert on a class.
/// @tparam Class The class that will be checked for the presence of a insert function.
template<typename Class>
using InsertValue_t = std::is_detected<InsertValueFunct_t,Class>;
/// @brief Convenience function for the value of a HasInsertValue check.
/// @tparam Class The class that will be checked for the presence of a "insert(class::value_type)" function.
/// @return Returns true if the provided type has a "insert()" member function that accepts a value, false otherwise.
template<typename Class>
constexpr Boole HasInsertValue()
{ return InsertValue_t<Class>::value; }

/// @brief Convenience type for add(value) function detection.
/// @tparam Class The class to test.
template<typename Class>
using AddValueFunct_t = decltype(std::declval<Class&>().add(std::declval<typename Class::value_type>()));
/// @brief Type for is_detected that tests for the existence of add on a class.
/// @tparam Class The class that will be checked for the presence of a insert function.
template<typename Class>
using AddValue_t = std::is_detected<AddValueFunct_t,Class>;
/// @brief Convenience function for the value of a HasAddValue check.
/// @tparam Class The class that will be checked for the presence of a "add(class::value_type)" function.
/// @return Returns true if the provided type has a "add()" member function that accepts a value, false otherwise.
template<typename Class>
constexpr Boole HasAddValue()
{ return AddValue_t<Class>::value; }

/// @brief Dummy/failure type for detecting if a class has a "value_type" defined.
/// @tparam Class The class to be tested.
template<typename Class, typename = void>
Expand Down Expand Up @@ -361,6 +406,9 @@ namespace ContainerDetect {
template<typename Comp, typename KeyType>
struct comp_is_transparent<Comp,KeyType,std::void_t<typename Comp::is_transparent>> : std::true_type
{ };



}//Mezzanine

#endif // Mezz_Foundation_ContainerTools_h
Loading