Fixed g++ incompatibility

This commit is contained in:
Leonetienne 2021-06-06 15:20:44 +02:00
parent 6974ae58ee
commit 09a2ce4e74
3 changed files with 219 additions and 146 deletions

View File

@ -463,6 +463,7 @@ std::string Hazelnupp::GenerateDocumentation() const
<< "==== AVAILABLE PARAMETERS ===="
<< std::endl << std::endl;
std::size_t counter = 0;
for (const auto& it : paramInfos)
{
const ParamDocEntry& pde = it.second;
@ -490,8 +491,11 @@ std::string Hazelnupp::GenerateDocumentation() const
if (pde.description.length() > 0)
ss << pde.description;
if (&it.second != &(paramInfos.cend().operator--())->second)
// Omit linebreaks when we're on the last element
if (counter < paramInfos.size()-1)
ss << std::endl << std::endl;
counter++;
}
}

View File

@ -137,27 +137,27 @@ void Hazelnupp::Parse(const int argc, const char* const* argv)
if ((!catchHelp) || (!HasParam("--help")))
ApplyConstraints();
}
catch (const HazelnuppConstraintTypeMissmatch& hctm)
catch (const HazelnuppConstraintTypeMissmatch& exc)
{
if (crashOnFail)
{
std::cout << GenerateDocumentation() << std::endl;
std::cerr << "Fatal error: Command-line parameter value-type mismatch at \"" << hctm.What() << "\"!";
std::cout << GenerateDocumentation() << std::endl << std::endl;
std::cerr << "Parameter error: " << exc.What() << std::endl;
quick_exit(-1009);
}
else
throw hctm; // yeet
throw exc; // yeet
}
catch (const HazelnuppConstraintMissingValue& hctm)
catch (const HazelnuppConstraintMissingValue& exc)
{
if (crashOnFail)
{
std::cout << GenerateDocumentation() << std::endl;
std::cerr << "Fatal error: Missing required command-line parameter \"" << hctm.What() << "\"!";
std::cout << GenerateDocumentation() << std::endl << std::endl;
std::cerr << "Parameter error: " << exc.What() << std::endl;
quick_exit(-1010);
}
else
throw hctm; // yeet
throw exc; // yeet
}
// Catch --help parameter
@ -241,28 +241,44 @@ bool Hazelnupp::HasParam(const std::string& key) const
Value* Hazelnupp::ParseValue(const std::vector<std::string>& values, const ParamConstraint* constraint)
{
// This is the raw (unconverted) data type the user provided
DATA_TYPE rawInputType;
// Constraint values
const bool constrainType = (constraint != nullptr) && (constraint->constrainType);
// Void-type
if (values.size() == 0)
{
rawInputType = DATA_TYPE::VOID;
// Is a list forced via a constraint? If yes, return an empty list
if ((constrainType) &&
(constraint->wantedType == DATA_TYPE::LIST))
return new ListValue();
// Is a string forced via a constraint? If yes, return an empty string
if ((constrainType) &&
else if ((constrainType) &&
(constraint->wantedType == DATA_TYPE::STRING))
return new StringValue("");
// Is an int or float forced via constraint? If yes, throw an exception
else if ((constrainType) &&
((constraint->wantedType == DATA_TYPE::INT) ||
(constraint->wantedType == DATA_TYPE::FLOAT)))
throw HazelnuppConstraintTypeMissmatch(
constraint->key,
constraint->wantedType,
rawInputType,
GetDescription(constraint->key)
);
// Else, just return the void type
return new VoidValue;
}
// Force void type by constraint
if ((constrainType) &&
else if ((constrainType) &&
(constraint->wantedType == DATA_TYPE::VOID))
{
return new VoidValue;
@ -271,11 +287,18 @@ Value* Hazelnupp::ParseValue(const std::vector<std::string>& values, const Param
// List-type
else if (values.size() > 1)
{
rawInputType = DATA_TYPE::LIST;
// Should the type be something other than list?
if ((constrainType) &&
(constraint->wantedType != DATA_TYPE::LIST))
{
throw HazelnuppConstraintTypeMissmatch(values[0] + " " + values[1]);
throw HazelnuppConstraintTypeMissmatch(
constraint->key,
constraint->wantedType,
rawInputType,
GetDescription(constraint->key)
);
}
ListValue* newList = new ListValue();
@ -294,6 +317,8 @@ Value* Hazelnupp::ParseValue(const std::vector<std::string>& values, const Param
// String
if (!StringTools::IsNumeric(val, true))
{
rawInputType = DATA_TYPE::STRING;
// Is the type not supposed to be a string?
// void and list are already sorted out
if ((constrainType) &&
@ -309,9 +334,14 @@ Value* Hazelnupp::ParseValue(const std::vector<std::string>& values, const Param
tmp = nullptr;
return list;
}
// Else it not possible to convert to a numeric
// Else it is not possible to convert to a numeric
else
throw HazelnuppConstraintTypeMissmatch(val);
throw HazelnuppConstraintTypeMissmatch(
constraint->key,
constraint->wantedType,
rawInputType,
GetDescription(constraint->key)
);
}
return new StringValue(val);
@ -329,6 +359,8 @@ Value* Hazelnupp::ParseValue(const std::vector<std::string>& values, const Param
if (StringTools::ParseNumber(val, isInt, num))
{
rawInputType = isInt ? DATA_TYPE::INT : DATA_TYPE::FLOAT;
// Is the type constrained?
// (only int and float left)
if (constrainType)
@ -503,6 +535,7 @@ std::string Hazelnupp::GenerateDocumentation() const
<< "==== AVAILABLE PARAMETERS ===="
<< std::endl << std::endl;
std::size_t counter = 0;
for (const auto& it : paramInfos)
{
const ParamDocEntry& pde = it.second;
@ -530,7 +563,11 @@ std::string Hazelnupp::GenerateDocumentation() const
if (pde.description.length() > 0)
ss << pde.description;
ss << std::endl << std::endl;
// Omit linebreaks when we're on the last element
if (counter < paramInfos.size()-1)
ss << std::endl << std::endl;
counter++;
}
}
@ -564,7 +601,10 @@ void Hazelnupp::ApplyConstraints()
// Is it important to have the missing parameter?
if (pc.second.required)
// Throw an error message then
throw HazelnuppConstraintMissingValue(pc.second.key);
throw HazelnuppConstraintMissingValue(
pc.second.key,
GetDescription(pc.second.key)
);
}
}

View File

@ -1,5 +1,18 @@
#pragma once
/*** ../Hazelnupp/Placeholders.h ***/
#include <string>
namespace Hazelnp
{
namespace Placeholders
{
//! The only purpose of this is to provide the ability to return an empty string as an error for std::string& methods.
static const std::string g_emptyString;
}
}
/*** ../Hazelnupp/StringTools.h ***/
#include <string>
@ -42,89 +55,6 @@ namespace Hazelnp
};
}
/*** ../Hazelnupp/Placeholders.h ***/
#include <string>
namespace Hazelnp
{
namespace Placeholders
{
//! The only purpose of this is to provide the ability to return an empty string as an error for std::string& methods.
static const std::string g_emptyString;
}
}
/*** ../Hazelnupp/HazelnuppException.h ***/
#include <stdexcept>
namespace Hazelnp
{
/** Generic hazelnupp exception
*/
class HazelnuppException : public std::exception
{
public:
HazelnuppException() {};
HazelnuppException(const std::string& msg) : message{ msg } {};
//! Will return an error message
const std::string& What() const
{
return message;
}
protected:
std::string message;
};
/** Gets thrown when an non-existent key gets dereferenced
*/
class HazelnuppInvalidKeyException : public HazelnuppException
{
public:
HazelnuppInvalidKeyException() : HazelnuppException() {};
HazelnuppInvalidKeyException(const std::string& msg) : HazelnuppException(msg) {};
};
/** Gets thrown when an attempt is made to retrieve the wrong data type from a value, when the value not convertible
*/
class HazelnuppValueNotConvertibleException : public HazelnuppException
{
public:
HazelnuppValueNotConvertibleException() : HazelnuppException() {};
HazelnuppValueNotConvertibleException(const std::string& msg) : HazelnuppException(msg) {};
};
/** Gets thrown something bad happens because of parameter constraints
*/
class HazelnuppConstraintException : public HazelnuppException
{
public:
HazelnuppConstraintException() : HazelnuppException() {};
HazelnuppConstraintException(const std::string& msg) : HazelnuppException(msg) {};
};
/** Gets thrown when a parameter is of a type that does not match the required type, and is not convertible to it
*/
class HazelnuppConstraintTypeMissmatch : public HazelnuppConstraintException
{
public:
HazelnuppConstraintTypeMissmatch() : HazelnuppConstraintException() {};
HazelnuppConstraintTypeMissmatch(const std::string& msg) : HazelnuppConstraintException(msg) {};
};
/** Gets thrown when a parameter constrained to be required is not provided, and has no default value set
*/
class HazelnuppConstraintMissingValue : public HazelnuppConstraintException
{
public:
HazelnuppConstraintMissingValue() : HazelnuppConstraintException() {};
HazelnuppConstraintMissingValue(const std::string& msg) : HazelnuppConstraintException(msg) {};
};
}
/*** ../Hazelnupp/DataType.h ***/
#include <string>
@ -236,6 +166,105 @@ namespace Hazelnp
};
}
/*** ../Hazelnupp/HazelnuppException.h ***/
#include <stdexcept>
#include <string>
#include <sstream>
namespace Hazelnp
{
/** Generic hazelnupp exception
*/
class HazelnuppException : public std::exception
{
public:
HazelnuppException() {};
HazelnuppException(const std::string& msg) : message{ msg } {};
//! Will return an error message
const std::string& What() const
{
return message;
}
protected:
std::string message;
};
/** Gets thrown when an non-existent key gets dereferenced
*/
class HazelnuppInvalidKeyException : public HazelnuppException
{
public:
HazelnuppInvalidKeyException() : HazelnuppException() {};
HazelnuppInvalidKeyException(const std::string& msg) : HazelnuppException(msg) {};
};
/** Gets thrown when an attempt is made to retrieve the wrong data type from a value, when the value not convertible
*/
class HazelnuppValueNotConvertibleException : public HazelnuppException
{
public:
HazelnuppValueNotConvertibleException() : HazelnuppException() {};
HazelnuppValueNotConvertibleException(const std::string& msg) : HazelnuppException(msg) {};
};
/** Gets thrown something bad happens because of parameter constraints
*/
class HazelnuppConstraintException : public HazelnuppException
{
public:
HazelnuppConstraintException() : HazelnuppException() {};
HazelnuppConstraintException(const std::string& msg) : HazelnuppException(msg) {};
};
/** Gets thrown when a parameter is of a type that does not match the required type, and is not convertible to it
*/
class HazelnuppConstraintTypeMissmatch : public HazelnuppConstraintException
{
public:
HazelnuppConstraintTypeMissmatch() : HazelnuppConstraintException() {};
HazelnuppConstraintTypeMissmatch(const std::string& msg) : HazelnuppConstraintException(msg) {};
HazelnuppConstraintTypeMissmatch(const std::string& key, const DATA_TYPE requiredType, const DATA_TYPE actualType, const std::string& paramDescription = "")
{
// Generate descriptive error message
std::stringstream ss;
ss << "Cannot convert parameter " << key << " to type " << DataTypeToString(requiredType)
<< ". You supplied type: " << DataTypeToString(actualType) << ".";
// Add the parameter description, if provided
if (paramDescription.length() > 0)
ss << std::endl << key << " => " << paramDescription;
message = ss.str();
return;
};
};
/** Gets thrown when a parameter constrained to be required is not provided, and has no default value set
*/
class HazelnuppConstraintMissingValue : public HazelnuppConstraintException
{
public:
HazelnuppConstraintMissingValue() : HazelnuppConstraintException() {};
HazelnuppConstraintMissingValue(const std::string& key, const std::string& paramDescription = "")
{
// Generate descriptive error message
std::stringstream ss;
ss << "Missing required parameter " << key << ".";
// Add the parameter description, if provided
if (paramDescription.length() > 0)
ss << std::endl << key << " => " << paramDescription;
message = ss.str();
return;
};
};
}
/*** ../Hazelnupp/Value.h ***/
#include <ostream>
@ -382,6 +411,53 @@ namespace Hazelnp
};
}
/*** ../Hazelnupp/IntValue.h ***/
namespace Hazelnp
{
/** Specializations for integer values (uses long long int)
*/
class IntValue : public Value
{
public:
IntValue(const long long int& value);
~IntValue() override {};
//! Will return a deeopopy of this object
Value* Deepcopy() const override;
//! Will return a string suitable for an std::ostream;
std::string GetAsOsString() const override;
//! Will return the raw value
const long long int& GetValue() const;
operator long long int() const;
operator int() const;
//! Will return the data as a long long int
long long int GetInt64() const override;
//! Will return the data as an int
int GetInt32() const override;
//! Will return the data as a long double
long double GetFloat64() const override;
//! Will return the data as a double
double GetFloat32() const override;
//! Will return the data as a string
std::string GetString() const override;
//! Throws HazelnuppValueNotConvertibleException
const std::vector<Value*>& GetList() const override;
private:
long long int value;
};
}
/*** ../Hazelnupp/VoidValue.h ***/
@ -449,53 +525,6 @@ namespace Hazelnp
};
}
/*** ../Hazelnupp/IntValue.h ***/
namespace Hazelnp
{
/** Specializations for integer values (uses long long int)
*/
class IntValue : public Value
{
public:
IntValue(const long long int& value);
~IntValue() override {};
//! Will return a deeopopy of this object
Value* Deepcopy() const override;
//! Will return a string suitable for an std::ostream;
std::string GetAsOsString() const override;
//! Will return the raw value
const long long int& GetValue() const;
operator long long int() const;
operator int() const;
//! Will return the data as a long long int
long long int GetInt64() const override;
//! Will return the data as an int
int GetInt32() const override;
//! Will return the data as a long double
long double GetFloat64() const override;
//! Will return the data as a double
double GetFloat32() const override;
//! Will return the data as a string
std::string GetString() const override;
//! Throws HazelnuppValueNotConvertibleException
const std::vector<Value*>& GetList() const override;
private:
long long int value;
};
}
/*** ../Hazelnupp/Hazelnupp.h ***/
#include <unordered_map>