mirror of https://github.com/procxx/kepka.git
				
				
				
			Alpha 1.0.21: Use custom refcount for MTP types.
It seems that heavy using std::shared_ptr and std::make_shared like it was before completely kills the compilation time. Also HistoryItem::_create now uses perfect forwarding.
This commit is contained in:
		
							parent
							
								
									f2cd364e14
								
							
						
					
					
						commit
						bc254228c9
					
				| 
						 | 
					@ -967,9 +967,9 @@ protected:
 | 
				
			||||||
template <typename T>
 | 
					template <typename T>
 | 
				
			||||||
class HistoryItemInstantiated {
 | 
					class HistoryItemInstantiated {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	template <typename ... Args>
 | 
						template <typename ...Args>
 | 
				
			||||||
	static T *_create(Args ... args) {
 | 
						static T *_create(Args &&... args) {
 | 
				
			||||||
		T *result = new T(args ...);
 | 
							T *result = new T(std::forward<Args>(args)...);
 | 
				
			||||||
		result->finishCreate();
 | 
							result->finishCreate();
 | 
				
			||||||
		return result;
 | 
							return result;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -174,28 +174,94 @@ public:
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class mtpData {
 | 
					namespace MTP {
 | 
				
			||||||
 | 
					namespace internal {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TypeData {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	virtual ~mtpData() {
 | 
						TypeData() = default;
 | 
				
			||||||
 | 
						TypeData(const TypeData &other) = delete;
 | 
				
			||||||
 | 
						TypeData(TypeData &&other) = delete;
 | 
				
			||||||
 | 
						TypeData &operator=(const TypeData &other) = delete;
 | 
				
			||||||
 | 
						TypeData &operator=(TypeData &&other) = delete;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void incrementCounter() const {
 | 
				
			||||||
 | 
							_counter.ref();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool decrementCounter() const {
 | 
				
			||||||
 | 
							return _counter.deref();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						virtual ~TypeData() {
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
						mutable QAtomicInt _counter = { 1 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class mtpDataOwner {
 | 
					class TypeDataOwner {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	mtpDataOwner(mtpDataOwner &&other) = default;
 | 
						TypeDataOwner(TypeDataOwner &&other) : _data(base::take(other._data)) {
 | 
				
			||||||
	mtpDataOwner(const mtpDataOwner &other) = default;
 | 
						}
 | 
				
			||||||
	mtpDataOwner &operator=(mtpDataOwner &&other) = default;
 | 
						TypeDataOwner(const TypeDataOwner &other) : _data(other._data) {
 | 
				
			||||||
	mtpDataOwner &operator=(const mtpDataOwner &other) = default;
 | 
							incrementCounter();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						TypeDataOwner &operator=(TypeDataOwner &&other) {
 | 
				
			||||||
 | 
							if (other._data != _data) {
 | 
				
			||||||
 | 
								decrementCounter();
 | 
				
			||||||
 | 
								_data = base::take(other._data);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return *this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						TypeDataOwner &operator=(const TypeDataOwner &other) {
 | 
				
			||||||
 | 
							if (other._data != _data) {
 | 
				
			||||||
 | 
								setData(other._data);
 | 
				
			||||||
 | 
								incrementCounter();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return *this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						~TypeDataOwner() {
 | 
				
			||||||
 | 
							decrementCounter();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
protected:
 | 
					protected:
 | 
				
			||||||
	mtpDataOwner() = default;
 | 
						TypeDataOwner() = default;
 | 
				
			||||||
	explicit mtpDataOwner(std::shared_ptr<const mtpData> &&data) : data(data) {
 | 
						TypeDataOwner(const TypeData *data) : _data(data) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	std::shared_ptr<const mtpData> data;
 | 
					
 | 
				
			||||||
 | 
						void setData(const TypeData *data) {
 | 
				
			||||||
 | 
							decrementCounter();
 | 
				
			||||||
 | 
							_data = data;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						template <typename DataType>
 | 
				
			||||||
 | 
						const DataType &queryData() const {
 | 
				
			||||||
 | 
							// Unsafe cast, type should be checked by the caller.
 | 
				
			||||||
 | 
							t_assert(_data != nullptr);
 | 
				
			||||||
 | 
							return static_cast<const DataType &>(*_data);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
						void incrementCounter() {
 | 
				
			||||||
 | 
							if (_data) {
 | 
				
			||||||
 | 
								_data->incrementCounter();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						void decrementCounter() {
 | 
				
			||||||
 | 
							if (_data && !_data->decrementCounter()) {
 | 
				
			||||||
 | 
								delete base::take(_data);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const TypeData * _data = nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace internal
 | 
				
			||||||
 | 
					} // namespace MTP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum {
 | 
					enum {
 | 
				
			||||||
	// core types
 | 
						// core types
 | 
				
			||||||
	mtpc_int = 0xa8509bda,
 | 
						mtpc_int = 0xa8509bda,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -94,7 +94,7 @@ with open('scheme.tl') as f:
 | 
				
			||||||
  for line in f:
 | 
					  for line in f:
 | 
				
			||||||
    layerline = re.match(r'// LAYER (\d+)', line)
 | 
					    layerline = re.match(r'// LAYER (\d+)', line)
 | 
				
			||||||
    if (layerline):
 | 
					    if (layerline):
 | 
				
			||||||
      layer = 'static constexpr mtpPrime CurrentLayer = ' + layerline.group(1) + ';';
 | 
					      layer = 'constexpr auto CurrentLayer = mtpPrime(' + layerline.group(1) + ');';
 | 
				
			||||||
    nocomment = re.match(r'^(.*?)//', line)
 | 
					    nocomment = re.match(r'^(.*?)//', line)
 | 
				
			||||||
    if (nocomment):
 | 
					    if (nocomment):
 | 
				
			||||||
      line = nocomment.group(1);
 | 
					      line = nocomment.group(1);
 | 
				
			||||||
| 
						 | 
					@ -571,7 +571,7 @@ for restype in typesList:
 | 
				
			||||||
    trivialConditions = data[7];
 | 
					    trivialConditions = data[7];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    dataText = '';
 | 
					    dataText = '';
 | 
				
			||||||
    dataText += '\nclass MTPD' + name + ' : public mtpData {\n'; # data class
 | 
					    dataText += '\nclass MTPD' + name + ' : public MTP::internal::TypeData {\n'; # data class
 | 
				
			||||||
    dataText += 'public:\n';
 | 
					    dataText += 'public:\n';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sizeList = [];
 | 
					    sizeList = [];
 | 
				
			||||||
| 
						 | 
					@ -606,20 +606,18 @@ for restype in typesList:
 | 
				
			||||||
    dataText += '\tMTPD' + name + '() = default;\n'; # default constructor
 | 
					    dataText += '\tMTPD' + name + '() = default;\n'; # default constructor
 | 
				
			||||||
    switchLines += '\t\tcase mtpc_' + name + ': '; # for by-type-id type constructor
 | 
					    switchLines += '\t\tcase mtpc_' + name + ': '; # for by-type-id type constructor
 | 
				
			||||||
    if (len(prms) > len(trivialConditions)):
 | 
					    if (len(prms) > len(trivialConditions)):
 | 
				
			||||||
      switchLines += 'data = std::make_shared<MTPD' + name + '>(); ';
 | 
					      switchLines += 'setData(new MTPD' + name + '()); ';
 | 
				
			||||||
      withData = 1;
 | 
					      withData = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      getters += '\tconst MTPD' + name + ' &c_' + name + '() const;\n'; # const getter
 | 
					      getters += '\tconst MTPD' + name + ' &c_' + name + '() const;\n'; # const getter
 | 
				
			||||||
      constructsInline += 'inline const MTPD' + name + ' &MTP' + restype + '::c_' + name + '() const {\n';
 | 
					      constructsInline += 'inline const MTPD' + name + ' &MTP' + restype + '::c_' + name + '() const {\n';
 | 
				
			||||||
      if (withType):
 | 
					      if (withType):
 | 
				
			||||||
        constructsInline += '\tt_assert(data != nullptr && _type == mtpc_' + name + ');\n';
 | 
					        constructsInline += '\tt_assert(_type == mtpc_' + name + ');\n';
 | 
				
			||||||
      else:
 | 
					      constructsInline += '\treturn queryData<MTPD' + name + '>();\n';
 | 
				
			||||||
        constructsInline += '\tt_assert(data != nullptr);\n';
 | 
					 | 
				
			||||||
      constructsInline += '\treturn static_cast<const MTPD' + name + '&>(*data);\n';
 | 
					 | 
				
			||||||
      constructsInline += '}\n';
 | 
					      constructsInline += '}\n';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      constructsText += '\texplicit MTP' + restype + '(std::shared_ptr<const MTPD' + name + '> &&data);\n'; # by-data type constructor
 | 
					      constructsText += '\texplicit MTP' + restype + '(const MTPD' + name + ' *data);\n'; # by-data type constructor
 | 
				
			||||||
      constructsInline += 'inline MTP' + restype + '::MTP' + restype + '(std::shared_ptr<const MTPD' + name + '> &&data) : mtpDataOwner(std::move(data))';
 | 
					      constructsInline += 'inline MTP' + restype + '::MTP' + restype + '(const MTPD' + name + ' *data) : TypeDataOwner(data)';
 | 
				
			||||||
      if (withType):
 | 
					      if (withType):
 | 
				
			||||||
        constructsInline += ', _type(mtpc_' + name + ')';
 | 
					        constructsInline += ', _type(mtpc_' + name + ')';
 | 
				
			||||||
      constructsInline += ' {\n}\n';
 | 
					      constructsInline += ' {\n}\n';
 | 
				
			||||||
| 
						 | 
					@ -667,7 +665,7 @@ for restype in typesList:
 | 
				
			||||||
      sizeCases += '\t\t\treturn ' + ' + '.join(sizeList) + ';\n';
 | 
					      sizeCases += '\t\t\treturn ' + ' + '.join(sizeList) + ';\n';
 | 
				
			||||||
      sizeCases += '\t\t}\n';
 | 
					      sizeCases += '\t\t}\n';
 | 
				
			||||||
      sizeFast = '\tconst MTPD' + name + ' &v(c_' + name + '());\n\treturn ' + ' + '.join(sizeList) + ';\n';
 | 
					      sizeFast = '\tconst MTPD' + name + ' &v(c_' + name + '());\n\treturn ' + ' + '.join(sizeList) + ';\n';
 | 
				
			||||||
      newFast = 'std::make_shared<MTPD' + name + '>()';
 | 
					      newFast = 'new MTPD' + name + '()';
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
      sizeFast = '\treturn 0;\n';
 | 
					      sizeFast = '\treturn 0;\n';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -681,7 +679,7 @@ for restype in typesList:
 | 
				
			||||||
      friendDecl += '\tfriend class MTP::internal::TypeCreator;\n';
 | 
					      friendDecl += '\tfriend class MTP::internal::TypeCreator;\n';
 | 
				
			||||||
    creatorProxyText += '\tinline static MTP' + restype + ' new_' + name + '(' + ', '.join(creatorParams) + ') {\n';
 | 
					    creatorProxyText += '\tinline static MTP' + restype + ' new_' + name + '(' + ', '.join(creatorParams) + ') {\n';
 | 
				
			||||||
    if (len(prms) > len(trivialConditions)): # creator with params
 | 
					    if (len(prms) > len(trivialConditions)): # creator with params
 | 
				
			||||||
      creatorProxyText += '\t\treturn MTP' + restype + '(std::make_shared<MTPD' + name + '>(' + ', '.join(creatorParamsList) + '));\n';
 | 
					      creatorProxyText += '\t\treturn MTP' + restype + '(new MTPD' + name + '(' + ', '.join(creatorParamsList) + '));\n';
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
      if (withType): # creator by type
 | 
					      if (withType): # creator by type
 | 
				
			||||||
        creatorProxyText += '\t\treturn MTP' + restype + '(mtpc_' + name + ');\n';
 | 
					        creatorProxyText += '\t\treturn MTP' + restype + '(mtpc_' + name + ');\n';
 | 
				
			||||||
| 
						 | 
					@ -698,9 +696,9 @@ for restype in typesList:
 | 
				
			||||||
      reader += '\t\tcase mtpc_' + name + ': _type = cons; '; # read switch line
 | 
					      reader += '\t\tcase mtpc_' + name + ': _type = cons; '; # read switch line
 | 
				
			||||||
      if (len(prms) > len(trivialConditions)):
 | 
					      if (len(prms) > len(trivialConditions)):
 | 
				
			||||||
        reader += '{\n';
 | 
					        reader += '{\n';
 | 
				
			||||||
        reader += '\t\t\tauto v = std::make_shared<MTPD' + name + '>();\n';
 | 
					        reader += '\t\t\tauto v = new MTPD' + name + '();\n';
 | 
				
			||||||
 | 
					        reader += '\t\t\tsetData(v);\n';
 | 
				
			||||||
        reader += readText;
 | 
					        reader += readText;
 | 
				
			||||||
        reader += '\t\t\tdata = std::move(v);\n';
 | 
					 | 
				
			||||||
        reader += '\t\t} break;\n';
 | 
					        reader += '\t\t} break;\n';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        writer += '\t\tcase mtpc_' + name + ': {\n'; # write switch line
 | 
					        writer += '\t\tcase mtpc_' + name + ': {\n'; # write switch line
 | 
				
			||||||
| 
						 | 
					@ -711,9 +709,9 @@ for restype in typesList:
 | 
				
			||||||
        reader += 'break;\n';
 | 
					        reader += 'break;\n';
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
      if (len(prms) > len(trivialConditions)):
 | 
					      if (len(prms) > len(trivialConditions)):
 | 
				
			||||||
        reader += '\n\tauto v = std::make_shared<MTPD' + name + '>();\n';
 | 
					        reader += '\n\tauto v = new MTPD' + name + '();\n';
 | 
				
			||||||
 | 
					        reader += '\tsetData(v);\n';
 | 
				
			||||||
        reader += readText;
 | 
					        reader += readText;
 | 
				
			||||||
        reader += '\tdata = std::move(v);\n';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        writer += '\tauto &v = c_' + name + '();\n';
 | 
					        writer += '\tauto &v = c_' + name + '();\n';
 | 
				
			||||||
        writer += writeText;
 | 
					        writer += writeText;
 | 
				
			||||||
| 
						 | 
					@ -722,14 +720,14 @@ for restype in typesList:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  typesText += '\nclass MTP' + restype; # type class declaration
 | 
					  typesText += '\nclass MTP' + restype; # type class declaration
 | 
				
			||||||
  if (withData):
 | 
					  if (withData):
 | 
				
			||||||
    typesText += ' : private mtpDataOwner'; # if has data fields
 | 
					    typesText += ' : private MTP::internal::TypeDataOwner'; # if has data fields
 | 
				
			||||||
  typesText += ' {\n';
 | 
					  typesText += ' {\n';
 | 
				
			||||||
  typesText += 'public:\n';
 | 
					  typesText += 'public:\n';
 | 
				
			||||||
  typesText += '\tMTP' + restype + '()'; # default constructor
 | 
					  typesText += '\tMTP' + restype + '()'; # default constructor
 | 
				
			||||||
  inits = [];
 | 
					  inits = [];
 | 
				
			||||||
  if not (withType):
 | 
					  if not (withType):
 | 
				
			||||||
    if (withData):
 | 
					    if (withData):
 | 
				
			||||||
      inits.append('mtpDataOwner(' + newFast + ')');
 | 
					      inits.append('TypeDataOwner(' + newFast + ')');
 | 
				
			||||||
  if (withData and not withType):
 | 
					  if (withData and not withType):
 | 
				
			||||||
    typesText += ';\n';
 | 
					    typesText += ';\n';
 | 
				
			||||||
    inlineMethods += '\ninline MTP' + restype + '::MTP' + restype + '()';
 | 
					    inlineMethods += '\ninline MTP' + restype + '::MTP' + restype + '()';
 | 
				
			||||||
| 
						 | 
					@ -770,9 +768,7 @@ for restype in typesList:
 | 
				
			||||||
  typesText += ');\n';
 | 
					  typesText += ');\n';
 | 
				
			||||||
  inlineMethods += 'inline void MTP' + restype + '::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) {\n';
 | 
					  inlineMethods += 'inline void MTP' + restype + '::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) {\n';
 | 
				
			||||||
  if (withData):
 | 
					  if (withData):
 | 
				
			||||||
    if (withType):
 | 
					    if not (withType):
 | 
				
			||||||
      inlineMethods += '\tdata.reset();\n';
 | 
					 | 
				
			||||||
    else:
 | 
					 | 
				
			||||||
      inlineMethods += '\tif (cons != mtpc_' + v[0][0] + ') throw mtpErrorUnexpected(cons, "MTP' + restype + '");\n';
 | 
					      inlineMethods += '\tif (cons != mtpc_' + v[0][0] + ') throw mtpErrorUnexpected(cons, "MTP' + restype + '");\n';
 | 
				
			||||||
  if (withType):
 | 
					  if (withType):
 | 
				
			||||||
    inlineMethods += '\tswitch (cons) {\n'
 | 
					    inlineMethods += '\tswitch (cons) {\n'
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
		Reference in New Issue