C++ String Non-Member Operator Overloading
Style Advice


Do not try to do too much on one line. Constructs such as if ((a = lhs.find(rhs, s_loc)) != -1) ++out, s_loc = a + 1; are difficult to read, difficult to parse and prone to errors. Instead, let each control statement have its own block, and do not abuse the comma operator to do completely unrelated things. For example, the line I mentioned should rather be something like

if ((a = lhs.find(rhs, s_loc)) != -1) {
    ++out;
    s_loc = a + 1;
}


or, even better,

a = lhs.find(rhs, s_loc);
if (a != -1) {
    ++out;
    s_loc = a + 1;
}






Avoid magic numbers. In particular, when checking the result of string::find, check whether the result is equal to std::string::npos, not -1. There even are some places in the code where you are already doing this, so please adopt it for the remaining places as well.
Prefer early return on failure. Concretely, in operator- you return an empty string only after you have checked for and possibly returned a valid result. Although this is quite minor, I would have expected the method to work the other way around, i. e.

if (loc == std::string::npos) {
    return std::string();
}
return lhs.substr(0, loc) + lhs.substr(loc + rhs.size());


which is quite a common pattern.
if (rhs == "") return static_cast&lt;unsigned long&gt;(-1); works but is not expressive. Prefer 

if (rhs.empty()) {
    return std::numeric_limits&lt;unsigned long&gt;::max();
}

while (rhs --&gt; 0) out += lhs; does nothing but obscure what is going on. --&gt; is not an operator in C++, so you should not write it as if it were one. Write while (rhs-- &gt; 0) ...
Remove the typo from the comment to operator-; what currently reads "occrance" should probably be "occurance".


Possible Optimizations

Although generally your code appears to work well, there are some things that you could easily implement to improve performance, mostly to avoid unnecessary copies. 

While it is good practice to implement operators in terms of other operators, the way that you implemented your operation + assignment-operators incurs making additional copies of your input. For example, let's consider operator% and operator%=:

inline std::string operator%(const std::string&amp; lhs, const std::string&amp; rhs) {
    //...
    auto out = lhs;
    //...
    return out;
}

inline std::string&amp; operator%=(std::string&amp; lhs, const std::string&amp; rhs) {

    return lhs = operator%(lhs, rhs);
}


Since operator% does not modify its inputs, it has to make a copy which is then modified and returned. However, operator%= does modify one of its inputs, in this case lhs, so making a copy, modifying it and reassigning it to lhs is unnecessary. Instead, you could approach the problem the other way around: First, implement operator%=, then implement operator% in terms of it: 

inline std::string&amp; operator%=(std::string&amp; lhs, const std::string&amp; rhs) {
    //perform in-place operation on lhs
    return lhs;
}

inline std::string operator%(const std::string&amp; lhs, const std::string&amp; rhs) {
    std::string out = lhs;
    out %= rhs;
    return out;
}