Skip to content

Commit

Permalink
Squashed 'externals/coda-oss/' changes from 70a006d8a..b6ead418c
Browse files Browse the repository at this point in the history
b6ead418c fix previous merge (#744)
07bcb3a39 Merge branch 'main' into cpp17
76beb7f34 Throwable always inherits from std::exception (#742)
959532681 reduce use of FmtX macro (#743)
f1a857cc4 Revert "simplify Throwable and friends: always derive from std::exception"
8d5f4402f simplify Throwable and friends: always derive from std::exception
fffac7fc4 Fix memory leaks in "cli" (#741)

git-subtree-dir: externals/coda-oss
git-subtree-split: b6ead418cfde26b016a3be199cd8ca7039a0a7be
  • Loading branch information
Dan Smith committed Oct 9, 2023
1 parent 8f4f58c commit 4c192d8
Show file tree
Hide file tree
Showing 35 changed files with 241 additions and 384 deletions.
70 changes: 43 additions & 27 deletions modules/c++/cli/include/cli/Results.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
#define CODA_OSS_cli_Results_h_INCLUDED_

#include <map>
#include <memory>
#include <utility>
#include <stdexcept>

#include "sys/Conf.h"

Expand All @@ -33,24 +36,25 @@
namespace cli
{

class Results
class Results final
{
protected:
typedef std::map<std::string, cli::Value*> ValueStorage_T;
typedef std::map<std::string, std::unique_ptr<cli::Value>> ValueStorage_T;
typedef ValueStorage_T::iterator ValueIter_T;
typedef ValueStorage_T::const_iterator ConstValueIter_T;
typedef std::map<std::string, cli::Results*> ResultsStorage_T;
typedef ResultsStorage_T::iterator ResultsIter_T;
typedef ResultsStorage_T::const_iterator ConstResultsIter_T;

public:
Results()
{
}
Results() = default;
~Results()
{
destroy();
}
Results(const Results&) = delete;
Results& operator=(const Results&) = delete;
Results(Results&&) = default;
Results& operator=(Results&&) = default;

bool hasValue(const std::string& key) const
{
Expand All @@ -62,20 +66,30 @@ class Results
return mResults.find(key) != mResults.end();
}

cli::Value* operator[](const std::string& key) const
const cli::Value* operator[](const std::string& key) const
{
return getValue(key);
}

cli::Value* getValue(const std::string& key) const
const cli::Value* getValue(const std::string& key) const
{
ConstValueIter_T p = mValues.find(key);
auto const p = mValues.find(key);
if (p == mValues.end())
{
const std::string errorMessage = "No argument named " + key;
throw except::NoSuchKeyException(Ctxt(errorMessage));
}
return p->second;
return p->second.get();
}
cli::Value* getValue(const std::string& key)
{
auto const p = mValues.find(key);
if (p == mValues.end())
{
const std::string errorMessage = "No argument named " + key;
throw except::NoSuchKeyException(Ctxt(errorMessage));
}
return p->second.get();
}

template<typename T>
Expand All @@ -100,15 +114,22 @@ class Results
return p->second;
}

void put(const std::string& key, cli::Value *value)
void put(const std::string& key, std::unique_ptr<cli::Value> value)
{
if (hasValue(key) && (getValue(key) == value.get()))
{
return;
}
mValues[key] = std::move(value);
}
void put(const std::string& key, cli::Value* value)
{
if (hasValue(key))
cli::Value* pExistingValue = hasValue(key) ? getValue(key) : nullptr;
if ((pExistingValue == nullptr) || (pExistingValue != value))
{
cli::Value* existing = getValue(key);
if (existing != value)
delete getValue(key);
// Either 1) we didn't already have a value or 2) the existing value is different
put(key, std::unique_ptr<cli::Value>(value));
}
mValues[key] = value;
}

void put(const std::string& key, cli::Results *args)
Expand All @@ -122,26 +143,21 @@ class Results
mResults[key] = args;
}

typedef ValueStorage_T::iterator iterator;
typedef ValueStorage_T::const_iterator const_iterator;
auto begin() { return mValues.begin(); }
auto begin() const { return mValues.begin(); }
auto end() { return mValues.end(); }
auto end() const { return mValues.end(); }

iterator begin() { return mValues.begin(); }
const_iterator begin() const { return mValues.begin(); }
iterator end() { return mValues.end(); }
const_iterator end() const { return mValues.end(); }

protected:
private:
ValueStorage_T mValues;
ResultsStorage_T mResults;

void destroy()
{
for (ValueIter_T it = mValues.begin(), end = mValues.end(); it != end; ++it)
delete it->second;
mValues.clear();
for (ResultsIter_T it = mResults.begin(), end = mResults.end(); it
!= end; ++it)
delete it->second;
mValues.clear();
mResults.clear();
}
};
Expand Down
27 changes: 4 additions & 23 deletions modules/c++/cli/include/cli/Value.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include <string>
#include <iterator>
#include <memory>

#include <import/str.h>
#include "sys/Conf.h"
Expand All @@ -38,12 +39,9 @@ namespace cli
* The Value class provides access to one or more actual values.
* It provides index-based access to parameters.
*/
class CODA_OSS_API Value
struct CODA_OSS_API Value final
{
public:
Value()
{
}
Value() = default;

template<typename T>
explicit Value(std::vector<T> value)
Expand All @@ -57,12 +55,6 @@ class CODA_OSS_API Value
set<T>(value);
}

template<typename T>
Value(T* value, size_t size, bool own = false)
{
set<T>(value, size, own);
}

~Value()
{
cleanup();
Expand All @@ -75,17 +67,6 @@ class CODA_OSS_API Value
mValues.push_back(str::toString(value));
}

template<typename T>
void set(T* value, size_t size, bool own = false)
{
cleanup();
mValues.reserve(size);
for (size_t i = 0; i < size; ++i)
add(value[i]);
if (own)
delete[] value;
}

template<typename T>
void setContainer(const std::vector<T>& c)
{
Expand All @@ -106,7 +87,7 @@ class CODA_OSS_API Value
{
if (index >= mValues.size())
throw except::IndexOutOfRangeException(
Ctxt(FmtX("Invalid index: %d", index)));
Ctxt(str::Format("Invalid index: %d", index)));
return str::toType<T>(mValues[index]);
}

Expand Down
2 changes: 1 addition & 1 deletion modules/c++/cli/source/Argument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ cli::Argument::~Argument()
cli::Argument* cli::Argument::addFlag(const std::string& flag)
{
char p = mParser->mPrefixChar;
std::string p2 = FmtX("%c%c", p, p);
std::string p2 = str::Format("%c%c", p, p);
if (flag.size() > 2 && str::startsWith(flag, p2) && flag[2] != p)
mLongFlags.push_back(validateFlag(flag.substr(2)));
else if (flag.size() > 1 && flag[0] == p && flag[1] != p)
Expand Down
Loading

0 comments on commit 4c192d8

Please sign in to comment.