I am putting together a set of policy classes that operate a number of operations to a string. I would like these policies to be exchangeable, but the "do nothing" policy is problematic too me, as:
- I don't see how to avoid copy using move semantic while maintaining the same (non-move) interface with the sister policies
- The compiler should know that the call to the policy can be inlined and evaluated at compile time, but it does not accept
constexpr
because the return type is a string.
#include <string>
#include<regex>
#include<cassert>
///
/// @brief Do not change anything
///
struct identity
{
static std::string edit(std::string&& s) // can not use constexpr: return type not a literal
{
return std::move(s);
}
};
///
/// @brief Template class.
///
template<unsigned int N>
struct remove_comments_of_depth
{};
///
/// @brief Do not remove anything
///
template<> struct remove_comments_of_depth<0> : identity
{};
///
/// @brief Remove all comments substrings contained between square brackets
///
/// @note Assumes that text is well formatted so there are no such things like [[]] or unclosed bracket
///
template<> struct remove_comments_of_depth<1>
{
static std::string edit(const std::string& s)
{
return std::regex_replace(s, std::regex(R"(\[[^()]*\])"), "");
}
};
int main(int argc, char *argv[])
{
std::string s = "my_string[this is a comment]";
auto copy = s;
assert(remove_comments_of_depth<1>::edit(s) == "my_string");
assert(remove_comments_of_depth<0>::edit(std::move(copy)) == s); // <<< how to avoid this call to std::move
}
What is the "standard" way to go in this kind of situation?