#include <type_traits>
#include <memory>
#include <iterator>
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <vector>
#include <list>
template < typename ALLOCATOR, typename T >
using rebind_to_type = typename std::allocator_traits<ALLOCATOR>::template rebind_alloc<T> ;
template < typename ALLOCATOR, typename FN, typename T >
using rebind_to_result_type = rebind_to_type< ALLOCATOR, typename std::result_of< FN(T) >::type > ;
template < typename U, typename T, typename A, template<typename,typename> class CONTAINER >
CONTAINER< U, rebind_to_type<A,U> > adapt( const CONTAINER<T,A>& c )
{ return CONTAINER< U, rebind_to_type<A,U> >( c.begin(), c.end() ) ; }
template < typename T, typename A, template<typename,typename> class CONTAINER, typename FN >
CONTAINER< typename std::result_of< FN(T) >::type, rebind_to_result_type<A,FN,T> >
adapt( const CONTAINER<T,A>& c, FN fn )
{
CONTAINER< typename std::result_of< FN(T) >::type, rebind_to_result_type<A,FN,T> > result ;
std::transform( c.begin(), c.end(), std::back_inserter(result), fn ) ;
return result ;
}
int main()
{
std::cout << std::fixed << std::showpoint << std::setprecision(2) ;
std::vector<int> vec { 64, 74, 77, 87, 58, 58, 75, 87 } ;
for( auto i : vec ) std::cout << i << ' ' ;
std::cout << '\n' ;
// implicit conversion int to double => std::vector<int> => std::vector<double>
auto vec2 = adapt<double>(vec) ;
for( auto d : vec2 ) std::cout << d << ' ' ;
std::cout << '\n' ;
std::list<short> lst( vec.rbegin(), vec.rend() ) ;
for( auto s : lst ) std::cout << s << ' ' ;
std::cout << '\n' ;
// explicit transformation short to double => std::list<short> => std::list<double>
auto lst2 = adapt( lst, [] ( int v ) { return v*v / 100.0 ; } ) ;
for( auto d : lst2 ) std::cout << d << ' ' ;
std::cout << '\n' ;
struct base { int i ; }; struct offset { int i ; }; struct derived : offset, base {} ;
std::vector<derived*> vec3 { new derived, new derived, new derived } ;
for( auto p : vec3 ) std::cout << p << ' ' ;
std::cout << '\n' ;
// implicit conversion derived* to base* => std::vector<base*> => std::vector<derived*>
std::vector<base*> vec4 = adapt<base*>(vec3) ;
for( auto p : vec4 ) std::cout << p << ' ' ;
std::cout << '\n' ;
}
I2luY2x1ZGUgPHR5cGVfdHJhaXRzPgojaW5jbHVkZSA8bWVtb3J5PgojaW5jbHVkZSA8aXRlcmF0b3I+CiNpbmNsdWRlIDxhbGdvcml0aG0+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPGlvbWFuaXA+CiNpbmNsdWRlIDx2ZWN0b3I+CiNpbmNsdWRlIDxsaXN0PgoKdGVtcGxhdGUgPCB0eXBlbmFtZSBBTExPQ0FUT1IsIHR5cGVuYW1lIFQgPgp1c2luZyByZWJpbmRfdG9fdHlwZSA9IHR5cGVuYW1lIHN0ZDo6YWxsb2NhdG9yX3RyYWl0czxBTExPQ0FUT1I+Ojp0ZW1wbGF0ZSByZWJpbmRfYWxsb2M8VD4gOwoKdGVtcGxhdGUgPCB0eXBlbmFtZSBBTExPQ0FUT1IsIHR5cGVuYW1lIEZOLCB0eXBlbmFtZSBUID4KdXNpbmcgcmViaW5kX3RvX3Jlc3VsdF90eXBlID0gcmViaW5kX3RvX3R5cGU8IEFMTE9DQVRPUiwgdHlwZW5hbWUgc3RkOjpyZXN1bHRfb2Y8IEZOKFQpID46OnR5cGUgPiA7Cgp0ZW1wbGF0ZSA8IHR5cGVuYW1lIFUsIHR5cGVuYW1lIFQsIHR5cGVuYW1lIEEsIHRlbXBsYXRlPHR5cGVuYW1lLHR5cGVuYW1lPiBjbGFzcyBDT05UQUlORVIgPgpDT05UQUlORVI8IFUsIHJlYmluZF90b190eXBlPEEsVT4gPiBhZGFwdCggY29uc3QgQ09OVEFJTkVSPFQsQT4mIGMgKQp7ICAgcmV0dXJuIENPTlRBSU5FUjwgVSwgcmViaW5kX3RvX3R5cGU8QSxVPiA+KCBjLmJlZ2luKCksIGMuZW5kKCkgKSA7IH0KCnRlbXBsYXRlIDwgdHlwZW5hbWUgVCwgdHlwZW5hbWUgQSwgdGVtcGxhdGU8dHlwZW5hbWUsdHlwZW5hbWU+IGNsYXNzIENPTlRBSU5FUiwgdHlwZW5hbWUgRk4gPgpDT05UQUlORVI8IHR5cGVuYW1lIHN0ZDo6cmVzdWx0X29mPCBGTihUKSA+Ojp0eXBlLCByZWJpbmRfdG9fcmVzdWx0X3R5cGU8QSxGTixUPiA+CmFkYXB0KCBjb25zdCBDT05UQUlORVI8VCxBPiYgYywgRk4gZm4gKQp7CiAgICBDT05UQUlORVI8IHR5cGVuYW1lIHN0ZDo6cmVzdWx0X29mPCBGTihUKSA+Ojp0eXBlLCByZWJpbmRfdG9fcmVzdWx0X3R5cGU8QSxGTixUPiA+IHJlc3VsdCA7CiAgICBzdGQ6OnRyYW5zZm9ybSggYy5iZWdpbigpLCBjLmVuZCgpLCBzdGQ6OmJhY2tfaW5zZXJ0ZXIocmVzdWx0KSwgZm4gKSA7CiAgICByZXR1cm4gcmVzdWx0IDsKfQoKaW50IG1haW4oKQp7CiAgICBzdGQ6OmNvdXQgPDwgc3RkOjpmaXhlZCA8PCBzdGQ6OnNob3dwb2ludCA8PCBzdGQ6OnNldHByZWNpc2lvbigyKSA7CgogICAgc3RkOjp2ZWN0b3I8aW50PiB2ZWMgeyA2NCwgNzQsIDc3LCA4NywgNTgsIDU4LCA3NSwgODcgfSA7CiAgICBmb3IoIGF1dG8gaSA6IHZlYyApIHN0ZDo6Y291dCA8PCBpIDw8ICcgJyA7CiAgICBzdGQ6OmNvdXQgPDwgJ1xuJyA7CgogICAgLy8gaW1wbGljaXQgY29udmVyc2lvbiBpbnQgdG8gZG91YmxlID0+IHN0ZDo6dmVjdG9yPGludD4gPT4gc3RkOjp2ZWN0b3I8ZG91YmxlPgogICAgYXV0byB2ZWMyID0gYWRhcHQ8ZG91YmxlPih2ZWMpIDsKICAgIGZvciggYXV0byBkIDogdmVjMiApIHN0ZDo6Y291dCA8PCBkIDw8ICcgJyA7CiAgICBzdGQ6OmNvdXQgPDwgJ1xuJyA7CgogICAgc3RkOjpsaXN0PHNob3J0PiBsc3QoIHZlYy5yYmVnaW4oKSwgdmVjLnJlbmQoKSApIDsKICAgIGZvciggYXV0byBzIDogbHN0ICkgc3RkOjpjb3V0IDw8IHMgPDwgJyAnIDsKICAgIHN0ZDo6Y291dCA8PCAnXG4nIDsKCiAgICAvLyBleHBsaWNpdCB0cmFuc2Zvcm1hdGlvbiBzaG9ydCB0byBkb3VibGUgPT4gc3RkOjpsaXN0PHNob3J0PiA9PiBzdGQ6Omxpc3Q8ZG91YmxlPgogICAgYXV0byBsc3QyID0gYWRhcHQoIGxzdCwgW10gKCBpbnQgdiApIHsgcmV0dXJuIHYqdiAvIDEwMC4wIDsgfSApIDsKICAgIGZvciggYXV0byBkIDogbHN0MiApIHN0ZDo6Y291dCA8PCBkIDw8ICcgJyA7CiAgICBzdGQ6OmNvdXQgPDwgJ1xuJyA7CgogICAgc3RydWN0IGJhc2UgeyBpbnQgaSA7IH07IHN0cnVjdCBvZmZzZXQgeyBpbnQgaSA7IH07IHN0cnVjdCBkZXJpdmVkIDogb2Zmc2V0LCBiYXNlIHt9IDsKICAgIHN0ZDo6dmVjdG9yPGRlcml2ZWQqPiB2ZWMzIHsgbmV3IGRlcml2ZWQsIG5ldyBkZXJpdmVkLCBuZXcgZGVyaXZlZCB9IDsKICAgIGZvciggYXV0byBwIDogdmVjMyApIHN0ZDo6Y291dCA8PCBwIDw8ICcgJyA7CiAgICBzdGQ6OmNvdXQgPDwgJ1xuJyA7CgogICAgLy8gaW1wbGljaXQgY29udmVyc2lvbiBkZXJpdmVkKiB0byBiYXNlKiA9PiBzdGQ6OnZlY3RvcjxiYXNlKj4gPT4gc3RkOjp2ZWN0b3I8ZGVyaXZlZCo+CiAgICBzdGQ6OnZlY3RvcjxiYXNlKj4gdmVjNCA9IGFkYXB0PGJhc2UqPih2ZWMzKSA7CiAgICBmb3IoIGF1dG8gcCA6IHZlYzQgKSBzdGQ6OmNvdXQgPDwgcCA8PCAnICcgOwogICAgc3RkOjpjb3V0IDw8ICdcbicgOwp9Cg==