1

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:

  1. Does this have huge performance issues? due to std::string construction. Normally internal buffers are about 0-31 in length, could increase in the future.
  2. Any other compact refactoring suggestions for this case, please suggest?

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.

PraAnj
  • 899
  • 1
  • 10
  • 27
  • 2
    Probably want `const std::string & Buffer,` as the first function parameter –  Aug 23 '18 at 16:49
  • ... unless you intend to alter or move the object (the mysterious `// do stuff ` will dictate that), in which case lose both the `const` and the reference. – WhozCraig Aug 23 '18 at 16:50
  • 1
    Take a look at `std::string_view` for the buffer parameter, but for the error parameter it's probably better to use std:;string& error. – Tony J Aug 23 '18 at 16:55
  • Marked duplicate is addressing something else. This is about converting internal buffers (char[]) into std::string. Internal char[] are already populated and not considered for performance in this case. – PraAnj Aug 23 '18 at 17:12

1 Answers1

1

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
Richard Hodges
  • 68,278
  • 7
  • 90
  • 142