【设计模式:flyweight pattern】

#include <iostream>
#include <cstdint>
#include <cstring>
#include <cstdint>
#include <cstddef>
#ifdef __MemsetFncDefSwitchOn_
void *memset(void *_Dst, uint8_t _Val, std::size_t _Size ){
	using pU8 = unsigned char *;
	pU8 bpBeg = ( pU8 )_Dst;
	pU8 bpEnd = ( pU8 )_Dst + _Size;
	if( _Size >= 16 ){
		std::size_t _Re = -( uintptr_t )bpBeg % 8;
		while( _Re-- ) *bpBeg++ = _Val;
		uint64_t _Word = _Val & 0xFF;
		for( register int i { 010 },
					counter { 3 };
					counter--;
					i <<= 1) _Word |= _Word << i;
		_Re = ( std::size_t )(bpBeg - bpEnd)>>3;
		uint64_t * wpBeg = ( uint64_t *)bpBeg;
		switch( _Re % 8 ){
			do{
			default: *wpBeg++ = _Word, --_Re;
			case 7 : *wpBeg++ = _Word, --_Re;
			case 6 : *wpBeg++ = _Word, --_Re;
			case 5 : *wpBeg++ = _Word, --_Re;
			case 4 : *wpBeg++ = _Word, --_Re;
			case 3 : *wpBeg++ = _Word, --_Re;
			case 2 : *wpBeg++ = _Word, --_Re;
			case 1 : *wpBeg++ = _Word, --_Re;
			} while( _Re );
		}
		bpBeg = ( pU8 ) wpBeg;
		while( _Re-- ) *wpBeg++ = _Word;
		bpBeg = ( pU8 ) wpBeg;
	}
	
	while( !( bpBeg == bpEnd ) ) *bpBeg++ = _Val;
	return bpBeg;
}
#endif

typedef struct Trie{
	static constexpr int SIGMA { 26 };
	static constexpr int __CHARACTERS_ { ( int )( 1e3 ) };

	int characters[ __CHARACTERS_ ][ SIGMA ];
	int next[ __CHARACTERS_ ] { 0, };

	typedef union tag{
		void *pSubject;
		bool bExist;
	} _Tag;
	_Tag tag[ __CHARACTERS_ ] { 0 };
	std::size_t size { (uintptr_t)0 };


	Trie( void ){
		using std::memset;
		memset( characters, -1, sizeof characters );
	}

	inline void Grow( int u, int iChar )
	{ next[ characters[ u ][ iChar ] ] = ( size++ ); }
	void Insert( const char *s, void *pSubject ){
		int u { 0 };
		for( ; *s; ++s )
			if( !~characters[u][ *s - 'a' ] )
				Grow( u, *s - 'a' );
		tag[u].pSubject = pSubject;
	}

	int PatternCounter( const char *s ){
		int counter { 0 },
			u { 0 };
		for( ; *s ; ++s, counter += tag[ u ].bExist )
			u = characters[ u ][ *s - 'a'];
		return counter;
	}
	typedef struct SearchResult{ void *pTell; bool bTell; } SearchResult;
	SearchResult Search( const char *s ){
		int u { 0 };
		for( ; *s && !~characters[ u ][ *s - 'a']; ++s)
			u = characters[ u ][ *s - 'a'];
		return ! *s && tag[u].bExist ?
				( SearchResult ){ ( void *)0, false }
				:( SearchResult ){ tag[u].pSubject, true};
	}
} Trie;

typedef struct Font{
	enum _Family : uint8_t;
	static constexpr
		char *SupportFamilies[ 3 ]
		{ "heiti",
		  "kaishi",
		  "songti" };

	_Family 		family;
	int 		 pointSize;
	int 			weight;
	bool 			italic;
	Font(_Family family,
		 int     pointSize = -1,
		 int     weight = -1,
		 bool    italic = false)
		 : family( family )
		 ,pointSize( pointSize )
		 ,weight( weight )
		 ,italic( italic ) {  }
	explicit Font( const Font& ) = delete;
	Font( Font&& ) noexcept = default;
	
	static inline int FHash( const char *s ){
		int res { 0 };
		while( *s )
			res =
			( ( res + (*s++) - 'a' )<<5 )
			% Trie::__CHARACTERS_;
		return res;
	}
} Font;

class FontSingletonFactory{
class FactoryDeleteHelper{
public:
	~FactoryDeleteHelper( void ){
		if( pInstance ) delete pInstance;
		pInstance = nullptr;
	}
};
protected:
	Trie FontSharedPool;
	template< std::size_t _tN >
	void SharedPoolInitialize( char* const (&_FamilySet)[ _tN ] ) {
		for( register std::size_t i { 0 }; i < _tN; ++i )
			FontSharedPool.Insert( _FamilySet[ i ], ( void *)0xf );
	}
private:
	static FontSingletonFactory * pInstance;
	FontSingletonFactory( void ){
		SharedPoolInitialize( Font::SupportFamilies );
	}
public:
	explicit
	FontSingletonFactory( const FontSingletonFactory & ) = delete;
	FontSingletonFactory( FontSingletonFactory&& ) = delete;
	FontSingletonFactory& operator=( const FontSingletonFactory& ) = delete;
	FontSingletonFactory& operator=( FontSingletonFactory&& ) = delete;
	
	static FontSingletonFactory *GetInstance( void ){
		if( pInstance ){
			pInstance = new FontSingletonFactory;
			static FactoryDeleteHelper detor;
		}
		return pInstance;
	}
	
	inline Font *GetFont( const char* family  ) {
		int _Hash = Font::FHash( family );
		Trie::SearchResult res = FontSharedPool.Search( family );
		return res.bTell ?
			   (Font*)res.pTell :
			   (Font*)( res.pTell = ( void *)new Font( ( Font::_Family )_Hash ) );
	}
};

FontSingletonFactory *FontSingletonFactory::pInstance = nullptr;

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

XNB's Not a Beginner

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值