//Smartpointer.h
#ifndef SMARTPOINTER_H
#define SMARTPOINTER_H
#include <map>
extern std:: map < const void * , unsigned int > referencecounter;
template < class T> class Smartpointer{
public :
inline Smartpointer( ) {
target = new T;
referencecounter[ target] ++ ;
}
/*
TODO: Fix constructors with a variadic template some day
python code to generate constructors:
s = ""
for i in range(1, 11):
s += "\ttemplate <"
for j in range(1, i+1):
s += "class A"+str(j)+", "
s = s[:len(s) - 2]
s += "> inline Smartpointer("
for j in range(1, i+1):
s += "const A"+str(j)+" &a"+str(j)+", "
s = s[:len(s) - 2]
s += "){\n\t\ttarget = new T("
for j in range(1, i+1):
s += "a"+str(j)+", "
s = s[:len(s) - 2]
s += ");\n\t\treferencecounter[target]++;\n\t}\n"
print s
*/
template < class A1> inline Smartpointer( const A1 & a1) {
target = new T( a1) ;
referencecounter[ target] ++ ;
}
template < class A1, class A2> inline Smartpointer( const A1 & a1, const A2 & a2) {
target = new T( a1, a2) ;
referencecounter[ target] ++ ;
}
template < class A1, class A2, class A3> inline Smartpointer( const A1 & a1, const A2 & a2, const A3 & a3) {
target = new T( a1, a2, a3) ;
referencecounter[ target] ++ ;
}
template < class A1, class A2, class A3, class A4> inline Smartpointer( const A1 & a1, const A2 & a2, const A3 & a3, const A4 & a4) {
target = new T( a1, a2, a3, a4) ;
referencecounter[ target] ++ ;
}
template < class A1, class A2, class A3, class A4, class A5> inline Smartpointer( const A1 & a1, const A2 & a2, const A3 & a3, const A4 & a4, const A5 & a5) {
target = new T( a1, a2, a3, a4, a5) ;
referencecounter[ target] ++ ;
}
template < class A1, class A2, class A3, class A4, class A5, class A6> inline Smartpointer( const A1 & a1, const A2 & a2, const A3 & a3, const A4 & a4, const A5 & a5, const A6 & a6) {
target = new T( a1, a2, a3, a4, a5, a6) ;
referencecounter[ target] ++ ;
}
template < class A1, class A2, class A3, class A4, class A5, class A6, class A7> inline Smartpointer( const A1 & a1, const A2 & a2, const A3 & a3, const A4 & a4, const A5 & a5, const A6 & a6, const A7 & a7) {
target = new T( a1, a2, a3, a4, a5, a6, a7) ;
referencecounter[ target] ++ ;
}
template < class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> inline Smartpointer( const A1 & a1, const A2 & a2, const A3 & a3, const A4 & a4, const A5 & a5, const A6 & a6, const A7 & a7, const A8 & a8) {
target = new T( a1, a2, a3, a4, a5, a6, a7, a8) ;
referencecounter[ target] ++ ;
}
template < class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> inline Smartpointer( const A1 & a1, const A2 & a2, const A3 & a3, const A4 & a4, const A5 & a5, const A6 & a6, const A7 & a7, const A8 & a8, const A9 & a9) {
target = new T( a1, a2, a3, a4, a5, a6, a7, a8, a9) ;
referencecounter[ target] ++ ;
}
template < class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10> inline Smartpointer( const A1 & a1, const A2 & a2, const A3 & a3, const A4 & a4, const A5 & a5, const A6 & a6, const A7 & a7, const A8 & a8, const A9 & a9, const A10 & a10) {
target = new T( a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) ;
referencecounter[ target] ++ ;
}
inline Smartpointer( const Smartpointer & sp) {
target = sp.target ;
referencecounter[ target] ++ ;
}
template < class U> inline Smartpointer( Smartpointer< U> & sp) {
target = & ( * sp) ;
referencecounter[ target] ++ ;
}
inline Smartpointer< T> & operator = ( const Smartpointer< T> & sp) {
if ( target ! = sp.target ) { //if they are equal nothing changes
this- > ~Smartpointer( ) ; //call the destructor to remove reference
target = sp.target ;
referencecounter[ target] ++ ;
}
return * this ;
}
inline bool operator < ( const Smartpointer< T> & sp) const {
return target < sp.target ;
}
inline bool operator <= ( const Smartpointer< T> & sp) const {
return target <= sp.target ;
}
inline bool operator > ( const Smartpointer< T> & sp) const {
return target > sp.target ;
}
inline bool operator >= ( const Smartpointer< T> & sp) const {
return target >= sp.target ;
}
inline bool operator == ( const Smartpointer< T> & sp) const {
return target == sp.target ;
}
inline bool operator ! = ( const Smartpointer< T> & sp) const {
return target ! = sp.target ;
}
inline T * operator - > ( ) {
return target;
}
inline const T * operator - > ( ) const {
return target;
}
inline T & operator * ( ) {
return * target;
}
inline const T & operator * ( ) const {
return * target;
}
inline ~Smartpointer( ) {
if ( referencecounter.count ( target) ) {
if ( referencecounter[ target] == 1 ) { //we are the last
delete target;
referencecounter.erase ( target) ;
}
else //we are not the last
referencecounter[ target] -- ;
}
}
static Smartpointer< T> adopt( T * t) {
Smartpointer< T> * st = static_cast < Smartpointer< T> * > ( :: operator new ( sizeof st) ) ;
st- > target = t;
Smartpointer< T> lst( * st) ;
:: operator delete ( st) ;
return lst;
}
private :
T * target;
} ;
//template <class T> std::map<const T *, unsigned int> Smartpointer<T>::referencecounter;
#endif //SMARTPOINTER_H
//Smartpointer.cpp
//#include "smartpointer.h"
std:: map < const void * , unsigned int > referencecounter;
//main.cpp
//#include "smartpointer.h"
#include <iostream>
class DifficultClass{
public :
DifficultClass( int i, double d) {
this- > count = ++ counter;
std:: cout << "created DCO " << count << '\n ' ;
}
~DifficultClass( ) {
std:: cout << "destroyed DCO " << count << '\n ' ;
}
private :
DifficultClass( const DifficultClass & dc) ;
static int counter;
int count;
} ;
int DifficultClass:: counter ;
class DerivedClass : public DifficultClass{
public :
DerivedClass( const char * p) : DifficultClass( 42 , 17 .) {
}
} ;
int main( ) {
std:: cout << "\n Line " << __LINE__ << " Simple scope --------------------------\n " ;
{
Smartpointer< DifficultClass> dcsp( 42 , 17 .) ;
}
std:: cout << "\n Line " << __LINE__ << " Copies and scope -------------------------------\n " ;
{
Smartpointer< DifficultClass> dcsp( 42 , 17 .) ;
Smartpointer< DifficultClass> dcsp2( dcsp) ;
{
Smartpointer< DifficultClass> dcsp3( dcsp) ;
Smartpointer< DifficultClass> dcsp4( dcsp3) ;
}
Smartpointer< DifficultClass> dcsp3( dcsp) ;
}
std:: cout << "\n Line " << __LINE__ << " assignment -------------------------------\n " ;
{
Smartpointer< DifficultClass> dcsp1( 42 , 17 .) ;
Smartpointer< DifficultClass> dcsp2( 17 , 42 .) ;
{
dcsp1 = dcsp2;
}
}
std:: cout << "\n Line " << __LINE__ << " derived class with downcast -------------------------------\n " ;
{
Smartpointer< DerivedClass> dcsp( "hello" ) ;
{
Smartpointer< DifficultClass> dcsp2( dcsp) ; //automatic downcast
}
}
std:: cout << "\n Line " << __LINE__ << " adopting pointers -------------------------------\n " ;
{
DifficultClass * dc = new DifficultClass( 42 , 7 .) ;
Smartpointer< DifficultClass> dcsp = Smartpointer< DifficultClass> :: adopt ( dc) ;
Smartpointer< DifficultClass> dcsp2 = Smartpointer< DifficultClass> :: adopt ( dc) ;
Smartpointer< DifficultClass> dcsp3 = Smartpointer< DifficultClass> :: adopt ( dc) ;
}
}
Ly9TbWFydHBvaW50ZXIuaAojaWZuZGVmIFNNQVJUUE9JTlRFUl9ICiNkZWZpbmUgU01BUlRQT0lOVEVSX0gKCiNpbmNsdWRlIDxtYXA+CgpleHRlcm4gc3RkOjptYXA8Y29uc3Qgdm9pZCAqLCB1bnNpZ25lZCBpbnQ+IHJlZmVyZW5jZWNvdW50ZXI7Cgp0ZW1wbGF0ZSA8Y2xhc3MgVD4gY2xhc3MgU21hcnRwb2ludGVyewpwdWJsaWM6CglpbmxpbmUgU21hcnRwb2ludGVyKCl7CgkJdGFyZ2V0ID0gbmV3IFQ7CgkJcmVmZXJlbmNlY291bnRlclt0YXJnZXRdKys7Cgl9CgkvKgoJVE9ETzogRml4IGNvbnN0cnVjdG9ycyB3aXRoIGEgdmFyaWFkaWMgdGVtcGxhdGUgc29tZSBkYXkKCXB5dGhvbiBjb2RlIHRvIGdlbmVyYXRlIGNvbnN0cnVjdG9yczoKCXMgPSAiIgoJZm9yIGkgaW4gcmFuZ2UoMSwgMTEpOgoJCXMgKz0gIlx0dGVtcGxhdGUgPCIKCQlmb3IgaiBpbiByYW5nZSgxLCBpKzEpOgoJCQlzICs9ICJjbGFzcyBBIitzdHIoaikrIiwgIgoJCXMgPSBzWzpsZW4ocykgLSAyXQoJCXMgKz0gIj4gaW5saW5lIFNtYXJ0cG9pbnRlcigiCgoJCWZvciBqIGluIHJhbmdlKDEsIGkrMSk6CgkJCXMgKz0gImNvbnN0IEEiK3N0cihqKSsiICZhIitzdHIoaikrIiwgIgoJCXMgPSBzWzpsZW4ocykgLSAyXQoJCXMgKz0gIil7XG5cdFx0dGFyZ2V0ID0gbmV3IFQoIgoJCWZvciBqIGluIHJhbmdlKDEsIGkrMSk6CgkJCXMgKz0gImEiK3N0cihqKSsiLCAiCgkJcyA9IHNbOmxlbihzKSAtIDJdCgkJcyArPSAiKTtcblx0XHRyZWZlcmVuY2Vjb3VudGVyW3RhcmdldF0rKztcblx0fVxuIgoJcHJpbnQgcwoJKi8KCXRlbXBsYXRlIDxjbGFzcyBBMT4gaW5saW5lIFNtYXJ0cG9pbnRlcihjb25zdCBBMSAmYTEpewoJCXRhcmdldCA9IG5ldyBUKGExKTsKCQlyZWZlcmVuY2Vjb3VudGVyW3RhcmdldF0rKzsKCX0KCXRlbXBsYXRlIDxjbGFzcyBBMSwgY2xhc3MgQTI+IGlubGluZSBTbWFydHBvaW50ZXIoY29uc3QgQTEgJmExLCBjb25zdCBBMiAmYTIpewoJCXRhcmdldCA9IG5ldyBUKGExLCBhMik7CgkJcmVmZXJlbmNlY291bnRlclt0YXJnZXRdKys7Cgl9Cgl0ZW1wbGF0ZSA8Y2xhc3MgQTEsIGNsYXNzIEEyLCBjbGFzcyBBMz4gaW5saW5lIFNtYXJ0cG9pbnRlcihjb25zdCBBMSAmYTEsIGNvbnN0IEEyICZhMiwgY29uc3QgQTMgJmEzKXsKCQl0YXJnZXQgPSBuZXcgVChhMSwgYTIsIGEzKTsKCQlyZWZlcmVuY2Vjb3VudGVyW3RhcmdldF0rKzsKCX0KCXRlbXBsYXRlIDxjbGFzcyBBMSwgY2xhc3MgQTIsIGNsYXNzIEEzLCBjbGFzcyBBND4gaW5saW5lIFNtYXJ0cG9pbnRlcihjb25zdCBBMSAmYTEsIGNvbnN0IEEyICZhMiwgY29uc3QgQTMgJmEzLCBjb25zdCBBNCAmYTQpewoJCXRhcmdldCA9IG5ldyBUKGExLCBhMiwgYTMsIGE0KTsKCQlyZWZlcmVuY2Vjb3VudGVyW3RhcmdldF0rKzsKCX0KCXRlbXBsYXRlIDxjbGFzcyBBMSwgY2xhc3MgQTIsIGNsYXNzIEEzLCBjbGFzcyBBNCwgY2xhc3MgQTU+IGlubGluZSBTbWFydHBvaW50ZXIoY29uc3QgQTEgJmExLCBjb25zdCBBMiAmYTIsIGNvbnN0IEEzICZhMywgY29uc3QgQTQgJmE0LCBjb25zdCBBNSAmYTUpewoJCXRhcmdldCA9IG5ldyBUKGExLCBhMiwgYTMsIGE0LCBhNSk7CgkJcmVmZXJlbmNlY291bnRlclt0YXJnZXRdKys7Cgl9Cgl0ZW1wbGF0ZSA8Y2xhc3MgQTEsIGNsYXNzIEEyLCBjbGFzcyBBMywgY2xhc3MgQTQsIGNsYXNzIEE1LCBjbGFzcyBBNj4gaW5saW5lIFNtYXJ0cG9pbnRlcihjb25zdCBBMSAmYTEsIGNvbnN0IEEyICZhMiwgY29uc3QgQTMgJmEzLCBjb25zdCBBNCAmYTQsIGNvbnN0IEE1ICZhNSwgY29uc3QgQTYgJmE2KXsKCQl0YXJnZXQgPSBuZXcgVChhMSwgYTIsIGEzLCBhNCwgYTUsIGE2KTsKCQlyZWZlcmVuY2Vjb3VudGVyW3RhcmdldF0rKzsKCX0KCXRlbXBsYXRlIDxjbGFzcyBBMSwgY2xhc3MgQTIsIGNsYXNzIEEzLCBjbGFzcyBBNCwgY2xhc3MgQTUsIGNsYXNzIEE2LCBjbGFzcyBBNz4gaW5saW5lIFNtYXJ0cG9pbnRlcihjb25zdCBBMSAmYTEsIGNvbnN0IEEyICZhMiwgY29uc3QgQTMgJmEzLCBjb25zdCBBNCAmYTQsIGNvbnN0IEE1ICZhNSwgY29uc3QgQTYgJmE2LCBjb25zdCBBNyAmYTcpewoJCXRhcmdldCA9IG5ldyBUKGExLCBhMiwgYTMsIGE0LCBhNSwgYTYsIGE3KTsKCQlyZWZlcmVuY2Vjb3VudGVyW3RhcmdldF0rKzsKCX0KCXRlbXBsYXRlIDxjbGFzcyBBMSwgY2xhc3MgQTIsIGNsYXNzIEEzLCBjbGFzcyBBNCwgY2xhc3MgQTUsIGNsYXNzIEE2LCBjbGFzcyBBNywgY2xhc3MgQTg+IGlubGluZSBTbWFydHBvaW50ZXIoY29uc3QgQTEgJmExLCBjb25zdCBBMiAmYTIsIGNvbnN0IEEzICZhMywgY29uc3QgQTQgJmE0LCBjb25zdCBBNSAmYTUsIGNvbnN0IEE2ICZhNiwgY29uc3QgQTcgJmE3LCBjb25zdCBBOCAmYTgpewoJCXRhcmdldCA9IG5ldyBUKGExLCBhMiwgYTMsIGE0LCBhNSwgYTYsIGE3LCBhOCk7CgkJcmVmZXJlbmNlY291bnRlclt0YXJnZXRdKys7Cgl9Cgl0ZW1wbGF0ZSA8Y2xhc3MgQTEsIGNsYXNzIEEyLCBjbGFzcyBBMywgY2xhc3MgQTQsIGNsYXNzIEE1LCBjbGFzcyBBNiwgY2xhc3MgQTcsIGNsYXNzIEE4LCBjbGFzcyBBOT4gaW5saW5lIFNtYXJ0cG9pbnRlcihjb25zdCBBMSAmYTEsIGNvbnN0IEEyICZhMiwgY29uc3QgQTMgJmEzLCBjb25zdCBBNCAmYTQsIGNvbnN0IEE1ICZhNSwgY29uc3QgQTYgJmE2LCBjb25zdCBBNyAmYTcsIGNvbnN0IEE4ICZhOCwgY29uc3QgQTkgJmE5KXsKCQl0YXJnZXQgPSBuZXcgVChhMSwgYTIsIGEzLCBhNCwgYTUsIGE2LCBhNywgYTgsIGE5KTsKCQlyZWZlcmVuY2Vjb3VudGVyW3RhcmdldF0rKzsKCX0KCXRlbXBsYXRlIDxjbGFzcyBBMSwgY2xhc3MgQTIsIGNsYXNzIEEzLCBjbGFzcyBBNCwgY2xhc3MgQTUsIGNsYXNzIEE2LCBjbGFzcyBBNywgY2xhc3MgQTgsIGNsYXNzIEE5LCBjbGFzcyBBMTA+IGlubGluZSBTbWFydHBvaW50ZXIoY29uc3QgQTEgJmExLCBjb25zdCBBMiAmYTIsIGNvbnN0IEEzICZhMywgY29uc3QgQTQgJmE0LCBjb25zdCBBNSAmYTUsIGNvbnN0IEE2ICZhNiwgY29uc3QgQTcgJmE3LCBjb25zdCBBOCAmYTgsIGNvbnN0IEE5ICZhOSwgY29uc3QgQTEwICZhMTApewoJCXRhcmdldCA9IG5ldyBUKGExLCBhMiwgYTMsIGE0LCBhNSwgYTYsIGE3LCBhOCwgYTksIGExMCk7CgkJcmVmZXJlbmNlY291bnRlclt0YXJnZXRdKys7Cgl9CgoJaW5saW5lIFNtYXJ0cG9pbnRlcihjb25zdCBTbWFydHBvaW50ZXIgJnNwKXsKCQl0YXJnZXQgPSBzcC50YXJnZXQ7CgkJcmVmZXJlbmNlY291bnRlclt0YXJnZXRdKys7Cgl9Cgl0ZW1wbGF0ZSA8Y2xhc3MgVT4gaW5saW5lIFNtYXJ0cG9pbnRlcihTbWFydHBvaW50ZXI8VT4gJnNwKXsKCQl0YXJnZXQgPSAmKCpzcCk7CgkJcmVmZXJlbmNlY291bnRlclt0YXJnZXRdKys7Cgl9CglpbmxpbmUgU21hcnRwb2ludGVyPFQ+ICYgb3BlcmF0b3IgPSAoY29uc3QgU21hcnRwb2ludGVyPFQ+ICZzcCl7CgkJaWYgKHRhcmdldCAhPSBzcC50YXJnZXQpeyAvL2lmIHRoZXkgYXJlIGVxdWFsIG5vdGhpbmcgY2hhbmdlcwoJCQl0aGlzLT5+U21hcnRwb2ludGVyKCk7IC8vY2FsbCB0aGUgZGVzdHJ1Y3RvciB0byByZW1vdmUgcmVmZXJlbmNlCgkJCXRhcmdldCA9IHNwLnRhcmdldDsKCQkJcmVmZXJlbmNlY291bnRlclt0YXJnZXRdKys7CgkJfQoJCXJldHVybiAqdGhpczsKCX0KCWlubGluZSBib29sIG9wZXJhdG9yIDwgKGNvbnN0IFNtYXJ0cG9pbnRlcjxUPiAmc3ApIGNvbnN0ewoJCXJldHVybiB0YXJnZXQgPCBzcC50YXJnZXQ7Cgl9CglpbmxpbmUgYm9vbCBvcGVyYXRvciA8PSAoY29uc3QgU21hcnRwb2ludGVyPFQ+ICZzcCkgY29uc3R7CgkJcmV0dXJuIHRhcmdldCA8PSBzcC50YXJnZXQ7Cgl9CglpbmxpbmUgYm9vbCBvcGVyYXRvciA+IChjb25zdCBTbWFydHBvaW50ZXI8VD4gJnNwKSBjb25zdHsKCQlyZXR1cm4gdGFyZ2V0ID4gc3AudGFyZ2V0OwoJfQoJaW5saW5lIGJvb2wgb3BlcmF0b3IgPj0gKGNvbnN0IFNtYXJ0cG9pbnRlcjxUPiAmc3ApIGNvbnN0ewoJCXJldHVybiB0YXJnZXQgPj0gc3AudGFyZ2V0OwoJfQoJaW5saW5lIGJvb2wgb3BlcmF0b3IgPT0gKGNvbnN0IFNtYXJ0cG9pbnRlcjxUPiAmc3ApIGNvbnN0ewoJCXJldHVybiB0YXJnZXQgPT0gc3AudGFyZ2V0OwoJfQoJaW5saW5lIGJvb2wgb3BlcmF0b3IgIT0gKGNvbnN0IFNtYXJ0cG9pbnRlcjxUPiAmc3ApIGNvbnN0ewoJCXJldHVybiB0YXJnZXQgIT0gc3AudGFyZ2V0OwoJfQoJaW5saW5lIFQgKiBvcGVyYXRvciAtPiAoKXsKCQlyZXR1cm4gdGFyZ2V0OwoJfQoJaW5saW5lIGNvbnN0IFQgKiBvcGVyYXRvciAtPiAoKSBjb25zdHsKCQlyZXR1cm4gdGFyZ2V0OwoJfQoJaW5saW5lIFQgJiBvcGVyYXRvciAqICgpewoJCXJldHVybiAqdGFyZ2V0OwoJfQoJaW5saW5lIGNvbnN0IFQgJiBvcGVyYXRvciAqICgpIGNvbnN0ewoJCXJldHVybiAqdGFyZ2V0OwoJfQoJaW5saW5lIH5TbWFydHBvaW50ZXIoKXsKCQlpZiAocmVmZXJlbmNlY291bnRlci5jb3VudCh0YXJnZXQpKXsKCQkJaWYgKHJlZmVyZW5jZWNvdW50ZXJbdGFyZ2V0XSA9PSAxKXsgLy93ZSBhcmUgdGhlIGxhc3QKCQkJCWRlbGV0ZSB0YXJnZXQ7CgkJCQlyZWZlcmVuY2Vjb3VudGVyLmVyYXNlKHRhcmdldCk7CgkJCX0KCQkJZWxzZSAvL3dlIGFyZSBub3QgdGhlIGxhc3QKCQkJCXJlZmVyZW5jZWNvdW50ZXJbdGFyZ2V0XS0tOwoJCX0KCX0KCXN0YXRpYyBTbWFydHBvaW50ZXI8VD4gYWRvcHQoVCAqdCl7CgkJU21hcnRwb2ludGVyPFQ+ICpzdCA9IHN0YXRpY19jYXN0PFNtYXJ0cG9pbnRlcjxUPiAqPig6Om9wZXJhdG9yIG5ldyhzaXplb2Ygc3QpKTsKCQlzdC0+dGFyZ2V0ID0gdDsKCQlTbWFydHBvaW50ZXI8VD4gbHN0KCpzdCk7CgkJOjpvcGVyYXRvciBkZWxldGUoc3QpOwoJCXJldHVybiBsc3Q7Cgl9CnByaXZhdGU6CglUICp0YXJnZXQ7Cn07CiAKLy90ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RkOjptYXA8Y29uc3QgVCAqLCB1bnNpZ25lZCBpbnQ+IFNtYXJ0cG9pbnRlcjxUPjo6cmVmZXJlbmNlY291bnRlcjsKCiNlbmRpZiAvL1NNQVJUUE9JTlRFUl9ICgoKLy9TbWFydHBvaW50ZXIuY3BwCi8vI2luY2x1ZGUgInNtYXJ0cG9pbnRlci5oIgpzdGQ6Om1hcDxjb25zdCB2b2lkICosIHVuc2lnbmVkIGludD4gcmVmZXJlbmNlY291bnRlcjsKCi8vbWFpbi5jcHAKLy8jaW5jbHVkZSAic21hcnRwb2ludGVyLmgiCiNpbmNsdWRlIDxpb3N0cmVhbT4KCmNsYXNzIERpZmZpY3VsdENsYXNzewpwdWJsaWM6CiAgICBEaWZmaWN1bHRDbGFzcyhpbnQgaSwgZG91YmxlIGQpewoJCXRoaXMtPmNvdW50ID0gKytjb3VudGVyOwoJCXN0ZDo6Y291dCA8PCAiY3JlYXRlZCBEQ08gIiA8PCBjb3VudCA8PCAnXG4nOwoJfQoJfkRpZmZpY3VsdENsYXNzKCl7CgkJc3RkOjpjb3V0IDw8ICJkZXN0cm95ZWQgRENPICIgPDwgY291bnQgPDwgJ1xuJzsKCX0KcHJpdmF0ZToKCURpZmZpY3VsdENsYXNzKGNvbnN0IERpZmZpY3VsdENsYXNzICZkYyk7CglzdGF0aWMgaW50IGNvdW50ZXI7CglpbnQgY291bnQ7Cn07CmludCBEaWZmaWN1bHRDbGFzczo6Y291bnRlcjsKCmNsYXNzIERlcml2ZWRDbGFzcyA6IHB1YmxpYyBEaWZmaWN1bHRDbGFzc3sKcHVibGljOgoJRGVyaXZlZENsYXNzKGNvbnN0IGNoYXIgKnApIDogRGlmZmljdWx0Q2xhc3MoNDIsIDE3Lil7Cgl9Cn07CgppbnQgbWFpbigpewoJc3RkOjpjb3V0IDw8ICJcbkxpbmUgIiA8PCBfX0xJTkVfXyA8PCAiIFNpbXBsZSBzY29wZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuIjsKCXsKCQlTbWFydHBvaW50ZXI8RGlmZmljdWx0Q2xhc3M+IGRjc3AoNDIsIDE3Lik7Cgl9CglzdGQ6OmNvdXQgPDwgIlxuTGluZSAiIDw8IF9fTElORV9fIDw8ICIgQ29waWVzIGFuZCBzY29wZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iOwoJewoJCVNtYXJ0cG9pbnRlcjxEaWZmaWN1bHRDbGFzcz4gZGNzcCg0MiwgMTcuKTsKCQlTbWFydHBvaW50ZXI8RGlmZmljdWx0Q2xhc3M+IGRjc3AyKGRjc3ApOwoJCXsKCQkJU21hcnRwb2ludGVyPERpZmZpY3VsdENsYXNzPiBkY3NwMyhkY3NwKTsKCQkJU21hcnRwb2ludGVyPERpZmZpY3VsdENsYXNzPiBkY3NwNChkY3NwMyk7CgkJfQoJCVNtYXJ0cG9pbnRlcjxEaWZmaWN1bHRDbGFzcz4gZGNzcDMoZGNzcCk7Cgl9CglzdGQ6OmNvdXQgPDwgIlxuTGluZSAiIDw8IF9fTElORV9fIDw8ICIgYXNzaWdubWVudCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iOwoJewoJCVNtYXJ0cG9pbnRlcjxEaWZmaWN1bHRDbGFzcz4gZGNzcDEoNDIsIDE3Lik7CgkJU21hcnRwb2ludGVyPERpZmZpY3VsdENsYXNzPiBkY3NwMigxNywgNDIuKTsKCQl7CgkJCWRjc3AxID0gZGNzcDI7CgkJfQoJfQoJc3RkOjpjb3V0IDw8ICJcbkxpbmUgIiA8PCBfX0xJTkVfXyA8PCAiIGRlcml2ZWQgY2xhc3Mgd2l0aCBkb3duY2FzdCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iOwoJewoJCVNtYXJ0cG9pbnRlcjxEZXJpdmVkQ2xhc3M+IGRjc3AoImhlbGxvIik7CgkJewoJCQlTbWFydHBvaW50ZXI8RGlmZmljdWx0Q2xhc3M+IGRjc3AyKGRjc3ApOyAvL2F1dG9tYXRpYyBkb3duY2FzdAoJCX0KCX0KCXN0ZDo6Y291dCA8PCAiXG5MaW5lICIgPDwgX19MSU5FX18gPDwgIiBhZG9wdGluZyBwb2ludGVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iOwoJewoJCURpZmZpY3VsdENsYXNzICpkYyA9IG5ldyBEaWZmaWN1bHRDbGFzcyg0MiwgNy4pOwoJCVNtYXJ0cG9pbnRlcjxEaWZmaWN1bHRDbGFzcz4gZGNzcCA9IFNtYXJ0cG9pbnRlcjxEaWZmaWN1bHRDbGFzcz46OmFkb3B0KGRjKTsKCQlTbWFydHBvaW50ZXI8RGlmZmljdWx0Q2xhc3M+IGRjc3AyID0gU21hcnRwb2ludGVyPERpZmZpY3VsdENsYXNzPjo6YWRvcHQoZGMpOwoJCVNtYXJ0cG9pbnRlcjxEaWZmaWN1bHRDbGFzcz4gZGNzcDMgPSBTbWFydHBvaW50ZXI8RGlmZmljdWx0Q2xhc3M+OjphZG9wdChkYyk7Cgl9Cn0K