Last active
December 26, 2015 19:58
-
-
Save mmocny/7204756 to your computer and use it in GitHub Desktop.
Motivated by http://ericniebler.com/2013/10/13/out-parameters-vs-move-semantics/ I'm playing with a possible simple solution to the problem of solving optionally useful InOut variables in C++11 given that the interface is ugly, but occasionally really necessary. Below is a seemingly working solution, which I truly suspected of being undefined be…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <string> | |
#include <algorithm> | |
/* | |
* Sample Output: http://ideone.com/EbKsF5 | |
* | |
* Tested on: g++ 4.7, g++ 4.8, clang 3.3 | |
* | |
*/ | |
// Use this class to wrap std::string, just to inject printing of calls to copy/move etc | |
struct StringWrapper : std::string { | |
// Any Constructor, including copy&move | |
template<class... T> | |
StringWrapper(T&&... t) : std::string(std::forward<T>(t)...) { | |
std::cout << __PRETTY_FUNCTION__ << std::endl; | |
} | |
// Any Assignment, including copy&move | |
template<class T> | |
StringWrapper& operator=(T&& other) { | |
std::string::operator=(std::forward<T>(other)); | |
std::cout << __PRETTY_FUNCTION__ << std::endl; | |
return *this; | |
} | |
~StringWrapper() { | |
std::cout << __PRETTY_FUNCTION__ << std::endl; | |
} | |
}; | |
// Utilities: dup, sorted, filtered | |
// ************************************* | |
// **** This is the interesting bit **** | |
// ************************************* | |
// | |
// The following duplicates a containers' content. | |
// | |
// It takes an option 2nd input-output argument as a hint. Input-Output in this case means that | |
// the result is written to it (output), but its original state (capacity) is used as "input". | |
// | |
template <class In, class InOut = StringWrapper> | |
InOut&& dup(In const& in, InOut&& inout = InOut{}) { | |
std::cout << __PRETTY_FUNCTION__ << std::endl; | |
std::cout << "cap: " << inout.capacity() << ", sz: " << inout.size() << std::endl; | |
inout.assign(std::begin(in), std::end(in)); | |
inout.append(std::begin(in), std::end(in)); | |
std::cout << "cap: " << inout.capacity() << ", sz: " << inout.size() << std::endl; | |
return std::forward<InOut>(inout); | |
} | |
// | |
// ************************************* | |
// ************************************* | |
template<class C> | |
C sorted(C c) { | |
std::sort(std::begin(c), std::end(c)); | |
return c; | |
} | |
template<class C, class T> | |
C filtered(C c, T&& t) { | |
c.erase(std::remove(std::begin(c), std::end(c), std::forward<T>(t)), std::end(c)); | |
return c; | |
} | |
// Now, lets test all the common possible use cases. | |
int main() { | |
std::string kInput = "long test string, >default string cap."; | |
{ | |
std::cout << "[Test] Good ol' fashioned Explicit-In-Out" << std::endl; | |
StringWrapper s; | |
s.reserve(100); | |
dup(kInput, s); | |
std::cout << s << std::endl; | |
} | |
{ | |
std::cout << "[Test] Temporary" << std::endl; | |
std::cout << dup(kInput) << std::endl; | |
} | |
{ | |
std::cout << "[Test] Temporary-with-Piped-Actions" << std::endl; | |
std::cout << filtered(sorted(dup(kInput)), 't') << std::endl; | |
} | |
{ | |
std::cout << "[Test] Temporary-with-Hint" << std::endl; | |
std::cout << dup(kInput, StringWrapper(100, ' ')) << std::endl; | |
} | |
{ | |
std::cout << "[Test] Move-Init-from-Temporary" << std::endl; | |
StringWrapper s = dup(kInput); | |
std::cout << s << std::endl; | |
} | |
{ | |
std::cout << "[Test] Move-Init-from-Temporary-with-Temporary-Hint" << std::endl; | |
StringWrapper s = dup(kInput, StringWrapper(100, ' ')); | |
std::cout << s << std::endl; | |
} | |
{ | |
std::cout << "[Test] Move-Assign-from-Temporary" << std::endl; | |
StringWrapper s; | |
s = dup(kInput); | |
std::cout << s << std::endl; | |
} | |
{ | |
std::cout << "[Test] Move-Assign-from-Temporary-with-Hint-of-Self" << std::endl; | |
StringWrapper s(100, ' '); | |
s = dup(kInput, s); | |
std::cout << s << std::endl; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment