I am working on a legacy C++ code and needs aggressive refactoring. Main problem in the code is, passing const char*
, char*
arguments heavily as below. const char*
variables are to pass internal char arrays (mostly user inputs) to validate and 'char*` to get any error details from the extended validators normally. This type of codes are everywhere in the codebase.
virtual bool ValidateField(const char* pointerToDataBuffer, char* error)
{
// extended codes by client teams.
}
I am thinking of changing the interfaces as below,
virtual bool ValidateField(const std::string copyOfBufferInside, std::string& error)
{
// do stuff as before.
}
My questions:
Note: Compiler is GCC 4.9.3.
EDITED: Internal buffer variables are in char[], not std::string. Might convert to std::string in the future. But that is not the case here.
Consider using type-based error-handling and boost::string_view to be able to handle all kinds of string-like inputs:
http://coliru.stacked-crooked.com/a/22e9ec17b14992d1
#include <string>
#include <boost/variant.hpp>
#include <boost/utility/string_view.hpp>
#include <iostream>
#include <type_traits>
struct validation
{
struct error
{
std::string message;
};
struct success
{
};
using result = boost::variant<success, error>;
template<class OnSuccess, class OnFailure>
struct visitor_impl : boost::static_visitor<void>
{
template<class A1, class A2>
visitor_impl(A1&& s, A2&& f)
: on_success(s)
, on_failure(f)
{}
void operator()(success const&) const
{
on_success();
}
void operator()(error const& f) const
{
on_failure(f.message);
}
OnSuccess on_success;
OnFailure on_failure;
};
template<class OnSuccess, class OnFailure>
static auto visitor(OnSuccess&& s, OnFailure&& f)
{
using success_f = typename std::decay<OnSuccess>::type;
using failure_f = typename std::decay<OnFailure>::type;
return visitor_impl<success_f, failure_f>
{
std::forward<OnSuccess>(s),
std::forward<OnFailure>(f)
};
}
};
validation::result ValidateField(boost::string_view value)
{
auto result = validation::result(validation::success {});
if (value != "foo")
result = validation::error { "not foo" };
return result;
}
int main()
{
std::string bar = "bar";
boost::apply_visitor(validation::visitor(
[]() { std::cout << "is foo\n"; },
[](std::string const& msg) { std::cout << msg << '\n'; }
), ValidateField(bar));
std::string foo = "foo";
boost::apply_visitor(validation::visitor(
[]() { std::cout << "is foo\n"; },
[](std::string const& msg) { std::cout << msg << '\n'; }
), ValidateField(foo));
const char* pfoo = "foo";
boost::apply_visitor(validation::visitor(
[]() { std::cout << "is foo\n"; },
[](std::string const& msg) { std::cout << msg << '\n'; }
), ValidateField(pfoo));
}
expected output:
not foo
is foo
is foo