diff --git a/examples/chip-tool/commands/common/Command.cpp b/examples/chip-tool/commands/common/Command.cpp index a7d0058b90624d..6969e3962c33a9 100644 --- a/examples/chip-tool/commands/common/Command.cpp +++ b/examples/chip-tool/commands/common/Command.cpp @@ -382,8 +382,7 @@ size_t Command::AddArgument(const char * name, const char * value, bool optional arg.value = const_cast(reinterpret_cast(value)); arg.optional = optional; - mArgs.emplace_back(arg); - return mArgs.size(); + return AddArgumentToList(std::move(arg)); } size_t Command::AddArgument(const char * name, char ** value, bool optional) @@ -394,8 +393,7 @@ size_t Command::AddArgument(const char * name, char ** value, bool optional) arg.value = reinterpret_cast(value); arg.optional = optional; - mArgs.emplace_back(arg); - return mArgs.size(); + return AddArgumentToList(std::move(arg)); } size_t Command::AddArgument(const char * name, chip::CharSpan * value, bool optional) @@ -406,8 +404,7 @@ size_t Command::AddArgument(const char * name, chip::CharSpan * value, bool opti arg.value = reinterpret_cast(value); arg.optional = optional; - mArgs.emplace_back(arg); - return mArgs.size(); + return AddArgumentToList(std::move(arg)); } size_t Command::AddArgument(const char * name, chip::ByteSpan * value, bool optional) @@ -418,8 +415,7 @@ size_t Command::AddArgument(const char * name, chip::ByteSpan * value, bool opti arg.value = reinterpret_cast(value); arg.optional = optional; - mArgs.emplace_back(arg); - return mArgs.size(); + return AddArgumentToList(std::move(arg)); } size_t Command::AddArgument(const char * name, AddressWithInterface * out, bool optional) @@ -430,8 +426,7 @@ size_t Command::AddArgument(const char * name, AddressWithInterface * out, bool arg.value = reinterpret_cast(out); arg.optional = optional; - mArgs.emplace_back(arg); - return mArgs.size(); + return AddArgumentToList(std::move(arg)); } size_t Command::AddArgument(const char * name, int64_t min, uint64_t max, void * out, ArgumentType type, bool optional) @@ -444,8 +439,7 @@ size_t Command::AddArgument(const char * name, int64_t min, uint64_t max, void * arg.max = max; arg.optional = optional; - mArgs.emplace_back(arg); - return mArgs.size(); + return AddArgumentToList(std::move(arg)); } size_t Command::AddArgument(const char * name, int64_t min, uint64_t max, void * out, bool optional) @@ -458,8 +452,7 @@ size_t Command::AddArgument(const char * name, int64_t min, uint64_t max, void * arg.max = max; arg.optional = optional; - mArgs.emplace_back(arg); - return mArgs.size(); + return AddArgumentToList(std::move(arg)); } const char * Command::GetArgumentName(size_t index) const @@ -486,3 +479,28 @@ const char * Command::GetAttribute(void) const return nullptr; } + +size_t Command::AddArgumentToList(Argument && argument) +{ + if (argument.optional || mArgs.empty() || !mArgs.back().optional) + { + // Safe to just append. + mArgs.emplace_back(std::move(argument)); + return mArgs.size(); + } + + // We're inserting a non-optional arg but we already have something optional + // in the list. Insert before the first optional arg. + for (auto cur = mArgs.cbegin(), end = mArgs.cend(); cur != end; ++cur) + { + if ((*cur).optional) + { + mArgs.emplace(cur, std::move(argument)); + return mArgs.size(); + } + } + + // Never reached. + VerifyOrDie(false); + return 0; +} diff --git a/examples/chip-tool/commands/common/Command.h b/examples/chip-tool/commands/common/Command.h index 29b480d5fd2ff0..9cbac4ba0c6ade 100644 --- a/examples/chip-tool/commands/common/Command.h +++ b/examples/chip-tool/commands/common/Command.h @@ -193,6 +193,12 @@ class Command size_t AddArgument(const char * name, int64_t min, uint64_t max, void * out, ArgumentType type, bool optional); size_t AddArgument(const char * name, int64_t min, uint64_t max, void * out, bool optional); + /** + * Add the Argument to our list. This preserves the property that all + * optional arguments come at the end of the list. + */ + size_t AddArgumentToList(Argument && argument); + const char * mName = nullptr; std::vector mArgs; };