Created
November 27, 2012 01:51
-
-
Save splinterofchaos/4151880 to your computer and use it in GitHub Desktop.
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 <algorithm> | |
#include <iostream> | |
#include <fstream> | |
#include <sstream> | |
template< class F, class G > struct AccumRight { | |
F f = F(); | |
G g = G(); | |
constexpr AccumRight() { } | |
constexpr AccumRight( F f, G g) | |
: f(f), g(g) { } | |
template< class X, class Y > | |
constexpr auto operator () ( X&& x, Y&& y ) | |
-> decltype( f(std::declval<X>(), g(std::declval<Y>()) ) ) | |
{ | |
return f( std::forward<X>(x), g(std::forward<Y>(y)) ); | |
} | |
}; | |
template< class F, class G, class A = AccumRight<F,G> > | |
constexpr A rAccumulation( F f, G g ) { | |
return A( f, g ); | |
} | |
namespace free_fn { | |
template< class X, class Y > | |
constexpr auto add( X&& x, Y&& y ) | |
-> decltype( std::declval<Y>() + std::declval<X>() ) | |
{ | |
return std::forward<X>(x) + std::forward<Y>(y); | |
} | |
template< class S > | |
int sum( const S& s ) { | |
using X = typename S::value_type; | |
return std::accumulate( s.begin(), s.end(), 0, | |
add<const X&,const X&> ); | |
} | |
} // namespace free | |
namespace obj { | |
struct Add { | |
template< class X, class Y > | |
constexpr auto operator () ( X&& x, Y&& y ) | |
-> decltype( std::declval<Y>() + std::declval<X>() ) | |
{ | |
return std::forward<X>(x) + std::forward<Y>(y); | |
} | |
}; | |
constexpr auto add = Add(); | |
struct Sum { | |
template< class S > | |
int operator () ( const S& s ) const { | |
using X = typename S::value_type; | |
return std::accumulate( s.begin(), s.end(), 0, add ); | |
} | |
}; | |
constexpr auto sum = Sum(); | |
} // namespace obj | |
struct Selector { | |
int i; | |
Selector( int j=0 ) : i(j) { } | |
template< class S > | |
typename S::value_type operator () ( const S& s ) const { | |
return *std::next( s.begin(), i ); | |
} | |
}; | |
namespace std { | |
template< class X > | |
string to_string( const std::vector<X>& v ) { | |
string str = "[ "; | |
for( const X& x : v ) str += to_string(x) + " "; | |
str += "]"; | |
return str; | |
} | |
// Because the standard doesn't define this. | |
string to_string( const std::string& s ) { | |
return s; | |
} | |
template< class T > | |
string to_string( const T& s ) { | |
ostringstream ss; | |
ss << s; | |
return ss.str(); | |
} | |
} // namespace std | |
struct Printer { | |
std::string destination; | |
Printer( std::string filename ) | |
: destination( std::move(filename) ) | |
{ | |
} | |
void redirect( std::string filename ) { | |
destination = std::move( filename ); | |
} | |
template< class X > | |
void operator () ( const X& x ) { | |
std::ofstream s( destination, std::ios_base::app ); | |
s << std::to_string(x); | |
} | |
}; | |
#include <ctime> | |
struct StampedPrinter : Printer { | |
StampedPrinter( std::string filename ) | |
: Printer( std::move(filename) ) | |
{ | |
} | |
template< class X > | |
void operator () ( const X& x ) { | |
std::time_t t = std::time( nullptr ); | |
std::tm tm = *std::localtime( &t ); | |
std::string time = std::to_string(tm.tm_min) + ":" + | |
std::to_string(tm.tm_sec) + " -- "; | |
Printer::operator()( time + std::to_string(x) + "\n" ); | |
} | |
}; | |
//template< class X > | |
//std::ostream& operator << ( std::ostream& os, const std::vector<X>& v ) { | |
// os << "[ "; | |
// for( const X& x : v ) os << x << ' '; | |
// os << ']'; | |
// return os; | |
//} | |
int main() { | |
int sum; | |
std::vector<int> v = { 1, 2, 3, 4, 5 }; | |
sum = std::accumulate( v.begin(), v.end(), 0, obj::add ); | |
std::cout << "sum = " << sum << std::endl; | |
Selector nth( 0 ); | |
std::cout << "first = " << nth(v) << std::endl; | |
nth.i = 2; | |
std::cout << "third = " << nth(v) << std::endl; | |
std::cout << "fourth = " << Selector(nth(v))(v) << std::endl; | |
std::vector<std::vector<int>> vv = { v, v, v }; | |
sum = std::accumulate( vv.begin(), vv.end(), 0, | |
rAccumulation(obj::add,obj::sum) ); | |
std::cout << "sum = " << sum << std::endl; | |
StampedPrinter prnt( "file1" ); | |
prnt( v ); | |
prnt.redirect( "file2" ); | |
prnt( vv ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment