I often need to write string processing functions that take an input string and transform that into some output string. I'm looking for a pattern to make such functions as generic as possible (with reasonable effort).RequirementsIt should be possible to supply the input as a range (like std::string or std::string_view), pair of iterators, null-terminated character arrays and pointers.Character type should not be restricted to char, but also support wchar_t. Support char16_t and char32_t only if it doesn't require additional effort as I currently have no use for them.Easy to use for the simple case where input and output is a std::basic_string.Easy to write and more importantly easy to read.Performance is less important. Processing character-by-character is good enough.I currently approach this by splitting the interface into two template functions. The first one is the idiomatic generic interface which is iterator based, the second one is range based for convenience. The convenience interface is allowed to trade some generalism for ease-of-use.ExampleEscape all occurences of the characters '\n', '\t' and '\\' in the input string.First the idiomatic interface.template< class InputIt, class OutputIt >OutputIt EscapeString( InputIt first, InputIt last, OutputIt out ){    while( first != last )    {        auto c = *first++;        switch( c )        {            case '\n':                *out++ = '\\';                *out++ = 'n';                break;            case '\t':                *out++ = '\\';                *out++ = 't';                break;            case '\\':                *out++ = '\\';                *out++ = '\\';                break;            default:                *out++ = c;        }    }    return out;}Now the convenience wrapper. InputString can be any string range (like std::string), null-terminated char array or pointer to null-terminated string.The result will be std::basic_string<character_type_of_InputString> by default, but can be changed to any class that has a push_back() member. template< typename InputString,           class ResultString = typename as_literal_traits<InputString>::std_string_type >ResultString EscapeStringCopy( const InputString& input ){    // Allow both the ADL-selected overloads for user-defined types and the standard     // library function templates to appear in the same overload set.    using std::begin; using std::end;    // Handle null-terminated character arrays, character pointers and ranges uniformly.     auto inputRange = boost::as_literal( input );    ResultString result;    EscapeString( begin( inputRange ), end( inputRange ), back_inserter( result ) );    return result;}The template as_literal_traits is an utility that is used to create a default return type of std::basic_string that has the same character type as the input string.template< typename StringT >struct as_literal_traits{    using range_type = decltype( boost::as_literal( StringT{} ) );    using value_type = typename boost::range_value< range_type >::type;    using std_string_type = std::basic_string< value_type >;};Live demo at ColiruAny improvements are welcome.
Pattern for writing a generic string transformation function
c++;strings;c++11;boost