Skip to content
This repository was archived by the owner on Aug 5, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 15 additions & 13 deletions parameter/ElementHandle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,20 @@ using std::string;
using std::mutex;
using std::lock_guard;

/** @return 0 by default, ie for non overloaded types. */
template <class T>
static size_t getUserInputSize(const T & /*scalar*/)
{
return 0;
}

/** @return the vector's size. */
template <class T>
static size_t getUserInputSize(const std::vector<T> &vector)
{
return vector.size();
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using SFINAL to test for size() method existence

/** @return 0 by default, ie for non overloaded types. */
 size_t getUserInputSize(...) { return 0; }

/** @return collection size if it has a size() method. does not participate to overload otherwise. */
template <class T, class..., class = decltype(&T::size)>
size_t getUserInputSize(T collection) { return collection.size(); }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure it is worth it: It works but only if I add an overload for std::string (it has a size method but we don't want to consider it as a collection). I can't guarantee, ahead of time, that no future "scalar" type will have a size() method. We would rely too much on future tests begin correctly written.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, then this should work:

template <class T>
size_t getUserInputSize(const T&) { return 0; }

template <class T>
size_t getUserInputSize(const std::vector<T> &t) { return t.size(); }

ElementHandle::ElementHandle(CConfigurableElement &element, CParameterMgr &parameterMgr)
: mElement(element), mParameterMgr(parameterMgr)
{
Expand Down Expand Up @@ -146,18 +160,6 @@ struct isVector<std::vector<T>> : std::true_type
{
};

template <class T>
size_t ElementHandle::getSize(T /*value*/)
{
return 0;
}

template <class T>
size_t ElementHandle::getSize(std::vector<T> &values)
{
return values.size();
}

bool ElementHandle::getAsXML(std::string &xmlValue, std::string &error) const
{
std::string result;
Expand Down Expand Up @@ -194,7 +196,7 @@ bool ElementHandle::setAsBytes(const std::vector<uint8_t> &bytesValue, std::stri
template <class T>
bool ElementHandle::setAs(const T value, string &error) const
{
if (not checkSetValidity(getSize(value), error)) {
if (not checkSetValidity(getUserInputSize(value), error)) {
return false;
}
// Safe downcast thanks to isParameter check in checkSetValidity
Expand Down
5 changes: 0 additions & 5 deletions parameter/include/ElementHandle.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,11 +234,6 @@ class PARAMETER_EXPORT ElementHandle
template <class T>
bool getAs(T &value, std::string &error) const;

template <class T>
static size_t getSize(T value);
template <class T>
static size_t getSize(std::vector<T> &values);

CBaseParameter &getParameter();
const CBaseParameter &getParameter() const;

Expand Down
42 changes: 42 additions & 0 deletions test/functional-tests/Handle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -602,4 +602,46 @@ SCENARIO("Mapping handle access", "[handler][mapping]")
}
}

SCENARIO_METHOD(SettingsTestPF, "Handle Get/Set as various kinds", "[handler][dynamic]")
{
ElementHandle intScalar(*this, "/test/test/parameter_block/integer");
WHEN ("Setting a scalar integer") {
WHEN ("As an array") {
THEN ("It should fail") {
CHECK_THROWS(intScalar.setAsIntegerArray({0, 0}));
}
}
WHEN ("As a scalalar") {
THEN ("It should succeed") {
uint32_t expected = 111;
CHECK_NOTHROW(intScalar.setAsInteger(expected));
AND_THEN ("Getting it back should give the same value") {
uint32_t back = 42;
CHECK_NOTHROW(intScalar.getAsInteger(back));
CHECK(back == expected);
}
}
}
}

ElementHandle intArray(*this, "/test/test/parameter_block/integer_array");
WHEN ("Setting a array integer") {
WHEN ("As a scalar") {
THEN ("It should fail") {
CHECK_THROWS(intArray.setAsSignedInteger(0));
}
}
WHEN ("As a integer") {
THEN ("It should succeed") {
const std::vector<int32_t> expected = {-9, 8, -7, 6};
CHECK_NOTHROW(intArray.setAsSignedIntegerArray(expected));
AND_THEN ("Getting it back should give the same value") {
std::vector<int32_t> back = {-42, 42, 43, -43};
CHECK_NOTHROW(intArray.getAsSignedIntegerArray(back));
CHECK(back == expected);
}
}
}
}
}
} // namespace parameterFramework
22 changes: 22 additions & 0 deletions test/functional-tests/include/ElementHandle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,28 @@ class ElementHandle : private FailureWrapper<::ElementHandle>
/** Wrap EH::getAsDouble to throw an exception on failure. */
void getAsDouble(double &value) const { mayFailCall(&EH::getAsDouble, value); }

void setAsInteger(uint32_t value) { mayFailCall(&EH::setAsInteger, value); }
void getAsInteger(uint32_t &value) const { mayFailCall(&EH::getAsInteger, value); }
void setAsIntegerArray(const std::vector<uint32_t> &value)
{
mayFailCall(&EH::setAsIntegerArray, value);
}
void getAsIntegerArray(std::vector<uint32_t> &value) const
{
mayFailCall(&EH::getAsIntegerArray, value);
}

void setAsSignedInteger(int32_t value) { mayFailCall(&EH::setAsSignedInteger, value); }
void getAsSignedInteger(int32_t &value) const { mayFailCall(&EH::getAsSignedInteger, value); }
void setAsSignedIntegerArray(const std::vector<int32_t> &value)
{
mayFailCall(&EH::setAsSignedIntegerArray, value);
}
void getAsSignedIntegerArray(std::vector<int32_t> &value) const
{
mayFailCall(&EH::getAsSignedIntegerArray, value);
}

std::string getStructureAsXML() const { return mayFailGet(&EH::getStructureAsXML); }

std::string getAsXML() const { return mayFailGet(&EH::getAsXML); }
Expand Down