#include <vector>
#include <algorithm>
#include <functional>
#include <iostream>
#include <typeinfo>
#include <string>
#include <memory>
#include <cxxabi.h>
template < class T>
std:: string type_name( )
{
typedef typename std:: remove_reference < T> :: type TR;
std:: unique_ptr < char , void ( * ) ( void * ) > own
(
abi:: __cxa_demangle( typeid ( TR) .name ( ) , nullptr,
nullptr, nullptr) ,
std:: free
) ;
std:: string r = own ! = nullptr? own.get ( ) : typeid ( TR) .name ( ) ;
if ( std:: is_const < TR> :: value )
r + = " const" ;
if ( std:: is_volatile < TR> :: value )
r + = " volatile" ;
if ( std:: is_lvalue_reference < T> :: value )
r + = " &" ;
else if ( std:: is_rvalue_reference < T> :: value )
r + = " &&" ;
return r;
}
template < class InputIt, class UnaryFunction>
UnaryFunction for_every( InputIt first, InputIt last, UnaryFunction f)
{
std:: cout << "Calling callable object of type " ;
std:: cout << type_name< UnaryFunction> ( ) << ".\n " ;
for ( ; first ! = last; ++ first)
{
f( * first) ;
}
std:: cout << "\n " ;
return f;
}
void d_to_cout( double const v) { std:: cout << v; }
void d_to_cout_sep( double const v, char const sep) { std:: cout << v << sep; }
struct d_printer
{
bool first = true ;
void operator ( ) ( double const v)
{
if ( ! first) std:: cout << ", " ;
std:: cout << v;
first = false ;
}
} ;
int main( )
{
std:: vector < double > const a{ 1.0 , 2.0 , 3.0 } ;
for_every( a.begin ( ) , a.end ( ) , & d_to_cout) ;
for_every( a.begin ( ) , a.end ( ) , std:: function < void ( double const ) > ( d_to_cout) ) ;
for_every( a.begin ( ) , a.end ( ) , d_printer( ) ) ;
for_every( a.begin ( ) , a.end ( ) , & d_to_cout) ;
for_every( a.begin ( ) , a.end ( ) , [ ] ( double const v) {
std:: cout << v;
} ) ;
for_every( a.begin ( ) , a.end ( ) , std:: bind (
d_to_cout_sep, std:: placeholders :: _1, '/'
) ) ;
return 0 ;
}
I2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPGZ1bmN0aW9uYWw+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPHR5cGVpbmZvPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8bWVtb3J5PgojaW5jbHVkZSA8Y3h4YWJpLmg+Cgp0ZW1wbGF0ZSA8Y2xhc3MgVD4Kc3RkOjpzdHJpbmcgdHlwZV9uYW1lKCkKewogIHR5cGVkZWYgdHlwZW5hbWUgc3RkOjpyZW1vdmVfcmVmZXJlbmNlPFQ+Ojp0eXBlIFRSOwogIHN0ZDo6dW5pcXVlX3B0cjxjaGFyLCB2b2lkKCopKHZvaWQqKT4gb3duCiAgICAoCiAgICBhYmk6Ol9fY3hhX2RlbWFuZ2xlKHR5cGVpZChUUikubmFtZSgpLCBudWxscHRyLAogICAgbnVsbHB0ciwgbnVsbHB0ciksCiAgICBzdGQ6OmZyZWUKICAgICk7CiAgc3RkOjpzdHJpbmcgciA9IG93biAhPSBudWxscHRyP293bi5nZXQoKTp0eXBlaWQoVFIpLm5hbWUoKTsKICBpZiAoc3RkOjppc19jb25zdDxUUj46OnZhbHVlKQogICAgciArPSAiIGNvbnN0IjsKICBpZiAoc3RkOjppc192b2xhdGlsZTxUUj46OnZhbHVlKQogICAgciArPSAiIHZvbGF0aWxlIjsKICBpZiAoc3RkOjppc19sdmFsdWVfcmVmZXJlbmNlPFQ+Ojp2YWx1ZSkKICAgIHIgKz0gIiAmIjsKICBlbHNlIGlmIChzdGQ6OmlzX3J2YWx1ZV9yZWZlcmVuY2U8VD46OnZhbHVlKQogICAgciArPSAiICYmIjsKICByZXR1cm4gcjsKfQoKdGVtcGxhdGU8Y2xhc3MgSW5wdXRJdCwgY2xhc3MgVW5hcnlGdW5jdGlvbj4KVW5hcnlGdW5jdGlvbiBmb3JfZXZlcnkoSW5wdXRJdCBmaXJzdCwgSW5wdXRJdCBsYXN0LCBVbmFyeUZ1bmN0aW9uIGYpCnsKICBzdGQ6OmNvdXQgPDwgIkNhbGxpbmcgY2FsbGFibGUgb2JqZWN0IG9mIHR5cGUgIjsKICBzdGQ6OmNvdXQgPDwgdHlwZV9uYW1lPFVuYXJ5RnVuY3Rpb24+KCkgPDwgIi5cbiI7CiAgZm9yICg7IGZpcnN0ICE9IGxhc3Q7ICsrZmlyc3QpCiAgewogICAgZigqZmlyc3QpOwogIH0KICBzdGQ6OmNvdXQgPDwgIlxuIjsKICByZXR1cm4gZjsKfQoKdm9pZCBkX3RvX2NvdXQoZG91YmxlIGNvbnN0IHYpIHsgc3RkOjpjb3V0IDw8IHY7IH0Kdm9pZCBkX3RvX2NvdXRfc2VwKGRvdWJsZSBjb25zdCB2LCBjaGFyIGNvbnN0IHNlcCkgeyBzdGQ6OmNvdXQgPDwgdiA8PCBzZXA7IH0KCnN0cnVjdCBkX3ByaW50ZXIKewogIGJvb2wgZmlyc3QgPSB0cnVlOwogIHZvaWQgb3BlcmF0b3IgKCkgKGRvdWJsZSBjb25zdCB2KQogIHsKICAgIGlmICghZmlyc3QpIHN0ZDo6Y291dCA8PCAiLCAiOwogICAgc3RkOjpjb3V0IDw8IHY7CiAgICBmaXJzdCA9IGZhbHNlOwogIH0KfTsKCgppbnQgbWFpbigpCnsKICBzdGQ6OnZlY3Rvcjxkb3VibGU+IGNvbnN0IGF7IDEuMCwgMi4wLCAzLjAgfTsKICBmb3JfZXZlcnkoYS5iZWdpbigpLCBhLmVuZCgpLCAmZF90b19jb3V0KTsKICBmb3JfZXZlcnkoYS5iZWdpbigpLCBhLmVuZCgpLCBzdGQ6OmZ1bmN0aW9uPHZvaWQoZG91YmxlIGNvbnN0KT4oZF90b19jb3V0KSk7CiAgZm9yX2V2ZXJ5KGEuYmVnaW4oKSwgYS5lbmQoKSwgZF9wcmludGVyKCkpOwogIGZvcl9ldmVyeShhLmJlZ2luKCksIGEuZW5kKCksICZkX3RvX2NvdXQpOwogIGZvcl9ldmVyeShhLmJlZ2luKCksIGEuZW5kKCksIFtdKGRvdWJsZSBjb25zdCB2KSB7CiAgICBzdGQ6OmNvdXQgPDwgdjsKICB9KTsKICBmb3JfZXZlcnkoYS5iZWdpbigpLCBhLmVuZCgpLCBzdGQ6OmJpbmQoCiAgICBkX3RvX2NvdXRfc2VwLCBzdGQ6OnBsYWNlaG9sZGVyczo6XzEsICcvJwogICkpOwogIHJldHVybiAwOwp9