Compare commits
	
		
			2566 Commits
		
	
	
		
			v3.2.35
			...
			services-a
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| d6691aea6b | |||
| 
						 | 
					115f00f5cd | ||
| 
						 | 
					e73f5fb9fe | ||
| 
						 | 
					cd0a381a35 | ||
| 
						 | 
					709296940c | ||
| 
						 | 
					00821945c5 | ||
| 
						 | 
					1d8a197242 | ||
| 
						 | 
					8e5fbef390 | ||
| 
						 | 
					15710ef814 | ||
| 
						 | 
					1554424e1b | ||
| 
						 | 
					8818a0381a | ||
| 
						 | 
					558f045b65 | ||
| 
						 | 
					dd848142ad | ||
| 
						 | 
					5f897468ef | ||
| 
						 | 
					84e66f8512 | ||
| 
						 | 
					6b0d52ca5b | ||
| 
						 | 
					acd0875f1d | ||
| 
						 | 
					b2d9b20edc | ||
| 
						 | 
					1b37eb1262 | ||
| 
						 | 
					89348910c3 | ||
| 
						 | 
					2f740564c6 | ||
| 
						 | 
					e04e0260c9 | ||
| 
						 | 
					e5ee28329d | ||
| 
						 | 
					0eb387d6de | ||
| 
						 | 
					0d11de4525 | ||
| 
						 | 
					82fd10408c | ||
| 
						 | 
					e2899ffa1d | ||
| 
						 | 
					7e6ac140c4 | ||
| 
						 | 
					d2214b8d2e | ||
| 
						 | 
					4e3de90cd0 | ||
| 
						 | 
					4262d9f051 | ||
| 
						 | 
					a73266dc4c | ||
| 
						 | 
					e8d0fa140a | ||
| 
						 | 
					7fb31de183 | ||
| 
						 | 
					1b07de6fa7 | ||
| 
						 | 
					63ce03680b | ||
| 
						 | 
					d5f8fa11d9 | ||
| 
						 | 
					7a4d03e2c1 | ||
| 
						 | 
					e13dbc621a | ||
| 
						 | 
					559d19018c | ||
| 
						 | 
					7a9a50d702 | ||
| 
						 | 
					98d534d5dd | ||
| 
						 | 
					26236fe63a | ||
| 
						 | 
					a3d06e6d77 | ||
| 
						 | 
					b37afd4269 | ||
| 
						 | 
					01e7cf44c2 | ||
| 
						 | 
					5809b32c98 | ||
| 
						 | 
					8748a52c68 | ||
| 
						 | 
					65f93168f2 | ||
| 
						 | 
					0e2fa42b60 | ||
| 
						 | 
					5f06b321b2 | ||
| 
						 | 
					146f549552 | ||
| 
						 | 
					8305b6cb1a | ||
| 
						 | 
					51a1d06c51 | ||
| 
						 | 
					63211c86de | ||
| 
						 | 
					de85a02f74 | ||
| 
						 | 
					8868ae956a | ||
| 
						 | 
					65e0740c49 | ||
| 
						 | 
					12413ad9e8 | ||
| 
						 | 
					5c0b20d06a | ||
| 
						 | 
					2ab0041180 | ||
| 
						 | 
					ab6b7102e0 | ||
| 
						 | 
					849ece4bb0 | ||
| 
						 | 
					2cf2665b84 | ||
| 
						 | 
					6b1226d5ea | ||
| 
						 | 
					eb77b208f8 | ||
| 
						 | 
					1e1e12fad2 | ||
| 
						 | 
					196dd55784 | ||
| 
						 | 
					3e758d2d5c | ||
| 
						 | 
					45c11135b8 | ||
| 
						 | 
					d9aeb88275 | ||
| 
						 | 
					f07e31de29 | ||
| 
						 | 
					13acdace42 | ||
| 
						 | 
					37178b2273 | ||
| 
						 | 
					85350e63ef | ||
| 
						 | 
					eb08c3facd | ||
| 
						 | 
					449fba03be | ||
| 
						 | 
					b06afd9074 | ||
| 
						 | 
					b72508546c | ||
| 
						 | 
					2b0c41609d | ||
| 
						 | 
					1e12ad344f | ||
| 
						 | 
					94caa9338a | ||
| 
						 | 
					2bd4c19a7d | ||
| 
						 | 
					6e9dac3417 | ||
| 
						 | 
					c506808d72 | ||
| 
						 | 
					d0ae922439 | ||
| 
						 | 
					45529ebdc1 | ||
| 
						 | 
					bc45f57b48 | ||
| 
						 | 
					ac265e6ff7 | ||
| 
						 | 
					1051033324 | ||
| 
						 | 
					a629e2650a | ||
| 
						 | 
					5346008b7a | ||
| 
						 | 
					cb42b3af6a | ||
| 
						 | 
					bcd753c28b | ||
| 
						 | 
					637084511e | ||
| 
						 | 
					32f8a3cbac | ||
| 
						 | 
					d2c3f7a326 | ||
| 
						 | 
					b57db97412 | ||
| 
						 | 
					cdd50681cd | ||
| 
						 | 
					18689074a8 | ||
| 
						 | 
					cfadf8f95a | ||
| 
						 | 
					ce1ecdba32 | ||
| 
						 | 
					848137390e | ||
| 
						 | 
					194ebeba94 | ||
| 
						 | 
					deb35d8b49 | ||
| 
						 | 
					44d12379bd | ||
| 
						 | 
					97da73b170 | ||
| 
						 | 
					083b0fb1e5 | ||
| 
						 | 
					d3a767bad8 | ||
| 
						 | 
					f6d1d81b01 | ||
| 
						 | 
					026d1cb5e4 | ||
| 
						 | 
					f55161c06a | ||
| 
						 | 
					757f8a8f9e | ||
| 
						 | 
					a6dd49ac07 | ||
| 
						 | 
					b7545fded3 | ||
| 
						 | 
					8688285a25 | ||
| 
						 | 
					741fe03969 | ||
| 
						 | 
					82b5d50c34 | ||
| 
						 | 
					350be92cd1 | ||
| 
						 | 
					fe45d32ef9 | ||
| 
						 | 
					db02ae0ce7 | ||
| 
						 | 
					ee90fee7bb | ||
| 
						 | 
					627cb6b90a | ||
| 
						 | 
					27934ddaac | ||
| 
						 | 
					8f82dc8668 | ||
| 
						 | 
					5f011e5d19 | ||
| 
						 | 
					e68f7b0bf3 | ||
| 
						 | 
					c5139e62bc | ||
| 
						 | 
					1c0559affa | ||
| 
						 | 
					d435ddd955 | ||
| 
						 | 
					5d1b94a708 | ||
| 
						 | 
					f24df7ccc9 | ||
| 
						 | 
					019450132e | ||
| 
						 | 
					1c2480a308 | ||
| 
						 | 
					d0bb6134ae | ||
| 
						 | 
					dac6931e81 | ||
| 
						 | 
					8bea736651 | ||
| 
						 | 
					da0ce1d3d6 | ||
| 
						 | 
					3ffa4f5bf6 | ||
| 
						 | 
					0d3519fe79 | ||
| 
						 | 
					ede1c29a0e | ||
| 
						 | 
					f496570df4 | ||
| 
						 | 
					367c434754 | ||
| 
						 | 
					4f585b6f2e | ||
| 
						 | 
					7790d52a4d | ||
| 
						 | 
					6ba8d9fd7d | ||
| 
						 | 
					8ebba4fcff | ||
| 
						 | 
					35998066c2 | ||
| 
						 | 
					cfc5b03264 | ||
| 
						 | 
					01564695a6 | ||
| 
						 | 
					7141450e37 | ||
| 
						 | 
					8edb5f4290 | ||
| 
						 | 
					0e9d7bc446 | ||
| 
						 | 
					f0d13fc9c4 | ||
| 
						 | 
					594bc5b169 | ||
| 
						 | 
					682cbe6951 | ||
| 
						 | 
					107def4594 | ||
| 
						 | 
					aee0786c22 | ||
| 
						 | 
					8bd2d684b9 | ||
| 
						 | 
					e5c2066d28 | ||
| 
						 | 
					f81383901d | ||
| 
						 | 
					4297a00537 | ||
| 
						 | 
					ff760d84a3 | ||
| 
						 | 
					af9b41e1a9 | ||
| 
						 | 
					b2337c82a7 | ||
| 
						 | 
					945180e1d3 | ||
| 
						 | 
					71d27eee8e | ||
| 
						 | 
					5846ea384a | ||
| 
						 | 
					a649b67880 | ||
| 
						 | 
					aaa82386d8 | ||
| 
						 | 
					63b0589382 | ||
| 
						 | 
					e1747af296 | ||
| 
						 | 
					183f88a846 | ||
| 
						 | 
					dcce7d8a57 | ||
| 
						 | 
					3594a64bd1 | ||
| 
						 | 
					42172826ca | ||
| 
						 | 
					d0dd4b765c | ||
| 
						 | 
					995f6c8ce3 | ||
| 
						 | 
					89ede4bcce | ||
| 
						 | 
					ec5a4cb423 | ||
| 
						 | 
					24de6b69c4 | ||
| 
						 | 
					0468ff400b | ||
| 
						 | 
					30e677a762 | ||
| 
						 | 
					bfb23b3b84 | ||
| 
						 | 
					dd2da734ba | ||
| 
						 | 
					4411c54ba2 | ||
| 
						 | 
					61f0100cd9 | ||
| 
						 | 
					1eba9c828c | ||
| 
						 | 
					5cad467a49 | ||
| 
						 | 
					35ae45e3ec | ||
| 
						 | 
					125a58f7c0 | ||
| 
						 | 
					814f5f0ccc | ||
| 
						 | 
					546a4d0bbb | ||
| 
						 | 
					3a04d27455 | ||
| 
						 | 
					74edf6aef4 | ||
| 
						 | 
					2a314bd06e | ||
| 
						 | 
					7e456d5a8c | ||
| 
						 | 
					2d2436f9a5 | ||
| 
						 | 
					7abbcd685e | ||
| 
						 | 
					d8415cfd53 | ||
| 
						 | 
					9bd600cab6 | ||
| 
						 | 
					d196dde23f | ||
| 
						 | 
					6ed627f7b7 | ||
| 
						 | 
					7a17df6bcd | ||
| 
						 | 
					19473f8b5d | ||
| 
						 | 
					0ed3dd4af9 | ||
| 
						 | 
					7f594b0069 | ||
| 
						 | 
					2b147a2998 | ||
| 
						 | 
					4a5e7af9a4 | ||
| 
						 | 
					628c98becb | ||
| 
						 | 
					e60d981e07 | ||
| 
						 | 
					cf9f283a8e | ||
| 
						 | 
					367c5097e0 | ||
| 
						 | 
					e5db326a7e | ||
| 
						 | 
					d4b0513993 | ||
| 
						 | 
					ca76392d28 | ||
| 
						 | 
					108b6759f7 | ||
| 
						 | 
					215b0790fd | ||
| 
						 | 
					ed1f4876aa | ||
| 
						 | 
					6b61197402 | ||
| 
						 | 
					125f54d830 | ||
| 
						 | 
					54d0e7dc53 | ||
| 
						 | 
					d940675445 | ||
| 
						 | 
					d4accae21b | ||
| 
						 | 
					309fa9718e | ||
| 
						 | 
					fb9b20e234 | ||
| 
						 | 
					1fb9af4823 | ||
| 
						 | 
					add7ed3731 | ||
| 
						 | 
					4eef62a481 | ||
| 
						 | 
					ed2a5a7973 | ||
| 
						 | 
					7c475e1198 | ||
| 
						 | 
					445f1c0f56 | ||
| 
						 | 
					74a5d76145 | ||
| 
						 | 
					4499d7590d | ||
| 
						 | 
					7b5a2ad68c | ||
| 
						 | 
					0eb84acc4b | ||
| 
						 | 
					675d17fe59 | ||
| 
						 | 
					aef757cc20 | ||
| 
						 | 
					6f346d635e | ||
| 
						 | 
					3637914aea | ||
| 
						 | 
					889d78deed | ||
| 
						 | 
					7ece6f9d2c | ||
| 
						 | 
					0cc8842c42 | ||
| 
						 | 
					364e940a9a | ||
| 
						 | 
					77d489b5e5 | ||
| 
						 | 
					44d26beb95 | ||
| 
						 | 
					4cb8962668 | ||
| 
						 | 
					440f704930 | ||
| 
						 | 
					6e8e8a3d1b | ||
| 
						 | 
					a62f060fdd | ||
| 
						 | 
					1efb12e332 | ||
| 
						 | 
					eb840d4117 | ||
| 
						 | 
					f4e3964ee5 | ||
| 
						 | 
					641e186b7c | ||
| 
						 | 
					a9ef587705 | ||
| 
						 | 
					d199288034 | ||
| 
						 | 
					47cbcbd348 | ||
| 
						 | 
					766c28ca82 | ||
| 
						 | 
					f4a80c1a01 | ||
| 
						 | 
					15b476bb80 | ||
| 
						 | 
					2b495a3781 | ||
| 
						 | 
					f2f1052da3 | ||
| 
						 | 
					d04f17bb72 | ||
| 
						 | 
					8925c34ff7 | ||
| 
						 | 
					63b7ecb97e | ||
| 
						 | 
					472c07008e | ||
| 
						 | 
					1b9d8b1f91 | ||
| 
						 | 
					f3f5bd8a5d | ||
| 
						 | 
					09ccdb4ecb | ||
| 
						 | 
					23c4aa0aa4 | ||
| 
						 | 
					0a0edfada0 | ||
| 
						 | 
					0500eb54da | ||
| 
						 | 
					60df29d734 | ||
| 
						 | 
					c2064124b9 | ||
| 
						 | 
					c2e4ba324f | ||
| 
						 | 
					7f51aac81b | ||
| 
						 | 
					57746be66e | ||
| 
						 | 
					0d1adc0692 | ||
| 
						 | 
					7dffabef43 | ||
| 
						 | 
					4d00eef822 | ||
| 
						 | 
					ea725da79b | ||
| 
						 | 
					1ac3459afa | ||
| 
						 | 
					1b235e56a3 | ||
| 
						 | 
					b8dd4ef20a | ||
| 
						 | 
					07e5a3a113 | ||
| 
						 | 
					7c55529072 | ||
| 
						 | 
					14419ac26f | ||
| 
						 | 
					d4a06b4477 | ||
| 
						 | 
					bf7983dac8 | ||
| 
						 | 
					1a865fd2fb | ||
| 
						 | 
					e1bb6f1eb3 | ||
| 
						 | 
					ead610b429 | ||
| 
						 | 
					9d324bcccd | ||
| 
						 | 
					680d4f8dc2 | ||
| 
						 | 
					2eff5f74a5 | ||
| 
						 | 
					d7df1a8eca | ||
| 
						 | 
					90fefa9382 | ||
| 
						 | 
					7b36dfb351 | ||
| 
						 | 
					1ca6b27afe | ||
| 
						 | 
					07e7757c31 | ||
| 
						 | 
					f56250624f | ||
| 
						 | 
					e781e4eb5f | ||
| 
						 | 
					427311f2c3 | ||
| 
						 | 
					22bd80daac | ||
| 
						 | 
					1b5206cb90 | ||
| 
						 | 
					93e9990df8 | ||
| 
						 | 
					6ffafe1c45 | ||
| 
						 | 
					5f8b6ed437 | ||
| 
						 | 
					e07b6c90d3 | ||
| 
						 | 
					3173a8ee3c | ||
| 
						 | 
					ca9006a1bc | ||
| 
						 | 
					8a8860e75c | ||
| 
						 | 
					1ca3ce7145 | ||
| 
						 | 
					15027f40b2 | ||
| 
						 | 
					4b3278058b | ||
| 
						 | 
					30f65a0b62 | ||
| 
						 | 
					8f836969eb | ||
| 
						 | 
					95aa8d8127 | ||
| 
						 | 
					246d3f243d | ||
| 
						 | 
					30a8b337e1 | ||
| 
						 | 
					c5929e30d1 | ||
| 
						 | 
					2ffcfb3ddd | ||
| 
						 | 
					e1b20fe0a9 | ||
| 
						 | 
					8ea7c578b3 | ||
| 
						 | 
					159eccbda0 | ||
| 
						 | 
					bc9d5aae58 | ||
| 
						 | 
					49d449c211 | ||
| 
						 | 
					ad8c87e5d3 | ||
| 
						 | 
					25250179da | ||
| 
						 | 
					cdb2eb8b9a | ||
| 
						 | 
					e0b820abbc | ||
| 
						 | 
					fe8939e745 | ||
| 
						 | 
					99d012c5ce | ||
| 
						 | 
					27329a497a | ||
| 
						 | 
					50f2a6ad4a | ||
| 
						 | 
					dfb778984c | ||
| 
						 | 
					179796d598 | ||
| 
						 | 
					2b40ab9a5b | ||
| 
						 | 
					b905afb169 | ||
| 
						 | 
					953479422c | ||
| 
						 | 
					cbdd3fc928 | ||
| 
						 | 
					5ff9fcd59a | ||
| 
						 | 
					e6ce29ed33 | ||
| 
						 | 
					4b87d094fb | ||
| 
						 | 
					a377df2e65 | ||
| 
						 | 
					7fa8fa680c | ||
| 
						 | 
					741c7b75d8 | ||
| 
						 | 
					7806d264ab | ||
| 
						 | 
					102c55d67d | ||
| 
						 | 
					6733815269 | ||
| 
						 | 
					b85fcff990 | ||
| 
						 | 
					55a2d71e3e | ||
| 
						 | 
					da7ec3f7cc | ||
| 
						 | 
					3fc8febeea | ||
| 
						 | 
					7157ed3854 | ||
| 
						 | 
					6c6b7956d2 | ||
| 
						 | 
					8d61345cd6 | ||
| 
						 | 
					cf88ddbaa5 | ||
| 
						 | 
					8e19d6080d | ||
| 
						 | 
					72bad83022 | ||
| 
						 | 
					3757fcf0bf | ||
| 
						 | 
					dc666d29b8 | ||
| 
						 | 
					8dfa123e81 | ||
| 
						 | 
					ef47932deb | ||
| 
						 | 
					f804965a8d | ||
| 
						 | 
					66f36b2d03 | ||
| 
						 | 
					0ddffad57c | ||
| 
						 | 
					b5e0ebe4c9 | ||
| 
						 | 
					3552691e57 | ||
| 
						 | 
					d12e40bc34 | ||
| 
						 | 
					ab8159a77f | ||
| 
						 | 
					f0fb39edd8 | ||
| 
						 | 
					0eb431dd2b | ||
| 
						 | 
					a9547af8e2 | ||
| 
						 | 
					b97a5d535c | ||
| 
						 | 
					950e9d1d0a | ||
| 
						 | 
					9f8b848631 | ||
| 
						 | 
					c0396cf28b | ||
| 
						 | 
					bf7f5c6032 | ||
| 
						 | 
					7d6a04d3a8 | ||
| 
						 | 
					543de65f33 | ||
| 
						 | 
					5769c9c6da | ||
| 
						 | 
					438e0c6575 | ||
| 
						 | 
					3bec262d2d | ||
| 
						 | 
					a899f76da2 | ||
| 
						 | 
					17e1027ea2 | ||
| 
						 | 
					8be65003ce | ||
| 
						 | 
					6678d95a5d | ||
| 
						 | 
					9e81d7cf21 | ||
| 
						 | 
					25bb41f549 | ||
| 
						 | 
					812d861307 | ||
| 
						 | 
					f53b064296 | ||
| 
						 | 
					c43deac0a6 | ||
| 
						 | 
					ea8b6255e3 | ||
| 
						 | 
					44da0b24e5 | ||
| 
						 | 
					ab7b78e9ce | ||
| 
						 | 
					79085b5e80 | ||
| 
						 | 
					ec30fe1b61 | ||
| 
						 | 
					3666e3af7b | ||
| 
						 | 
					cc90dcf556 | ||
| 
						 | 
					d77215c227 | ||
| 
						 | 
					8ca841d08e | ||
| 
						 | 
					2d0940e555 | ||
| 
						 | 
					11e1659cad | ||
| 
						 | 
					39e2b527eb | ||
| 
						 | 
					cb7258249d | ||
| 
						 | 
					e7161443d6 | ||
| 
						 | 
					baf580f0ac | ||
| 
						 | 
					25de501eb8 | ||
| 
						 | 
					e78f8840ea | ||
| 
						 | 
					f00fa429bf | ||
| 
						 | 
					48fd148b8a | ||
| 
						 | 
					240f18e5bd | ||
| 
						 | 
					1cec7912de | ||
| 
						 | 
					197cbec82c | ||
| 
						 | 
					f1e4bcd8e5 | ||
| 
						 | 
					20b4cefedb | ||
| 
						 | 
					33aeabd617 | ||
| 
						 | 
					1963dd3412 | ||
| 
						 | 
					c4496ef86b | ||
| 
						 | 
					1e2a51f952 | ||
| 
						 | 
					06d6f217b5 | ||
| 
						 | 
					63c3f68619 | ||
| 
						 | 
					ca2e36b3f3 | ||
| 
						 | 
					2f6eb272c1 | ||
| 
						 | 
					e01b45f008 | ||
| 
						 | 
					def9bf18d3 | ||
| 
						 | 
					5c4557e4d1 | ||
| 
						 | 
					9a88e0ab10 | ||
| 
						 | 
					7a67840c9b | ||
| 
						 | 
					d662fb084d | ||
| 
						 | 
					b2c75a1af8 | ||
| 
						 | 
					4bf1b0fa7e | ||
| 
						 | 
					f385c94729 | ||
| 
						 | 
					6eff07eff2 | ||
| 
						 | 
					29ef9e909d | ||
| 
						 | 
					5f51d84887 | ||
| 
						 | 
					9dfd83ab7c | ||
| 
						 | 
					69d771ae77 | ||
| 
						 | 
					9c2cbf7588 | ||
| 
						 | 
					25b9e23330 | ||
| 
						 | 
					b07f0c2857 | ||
| 
						 | 
					3ceee01713 | ||
| 
						 | 
					6a236f7695 | ||
| 
						 | 
					61cc9c9791 | ||
| 
						 | 
					2d118c7057 | ||
| 
						 | 
					81c87dc5ac | ||
| 
						 | 
					4f2ab856a3 | ||
| 
						 | 
					74d30afad6 | ||
| 
						 | 
					4844534d7d | ||
| 
						 | 
					d35e69c8a9 | ||
| 
						 | 
					9a75b68ed8 | ||
| 
						 | 
					70d4512635 | ||
| 
						 | 
					da295e00f9 | ||
| 
						 | 
					079f608700 | ||
| 
						 | 
					3a0cb8d1fd | ||
| 
						 | 
					f5b974984c | ||
| 
						 | 
					ce6f498358 | ||
| 
						 | 
					8e1bd367c4 | ||
| 
						 | 
					c296f67356 | ||
| 
						 | 
					5513ffcd1c | ||
| 
						 | 
					0038751106 | ||
| 
						 | 
					719c6f2ff1 | ||
| 
						 | 
					6c25be670d | ||
| 
						 | 
					ce9250acb5 | ||
| 
						 | 
					92a208104b | ||
| 
						 | 
					59fd4ee082 | ||
| 
						 | 
					bbc9d90888 | ||
| 
						 | 
					d448be1077 | ||
| 
						 | 
					48f61be73a | ||
| 
						 | 
					8ca6b56f56 | ||
| 
						 | 
					b7af2dd77d | ||
| 
						 | 
					1855e4f61e | ||
| 
						 | 
					d88d2ce92e | ||
| 
						 | 
					2f8ef8fdf3 | ||
| 
						 | 
					d45819d552 | ||
| 
						 | 
					f156fc3562 | ||
| 
						 | 
					400dc6cbcc | ||
| 
						 | 
					9050566bdb | ||
| 
						 | 
					cea2b1e8d8 | ||
| 
						 | 
					ba33908f9f | ||
| 
						 | 
					c54ce69e67 | ||
| 
						 | 
					ab51a2ea03 | ||
| 
						 | 
					ad0656953e | ||
| 
						 | 
					35e7474284 | ||
| 
						 | 
					a1c9dedc37 | ||
| 
						 | 
					8080adbce2 | ||
| 
						 | 
					35cc54a6b9 | ||
| 
						 | 
					e97d3134d6 | ||
| 
						 | 
					77e1407c51 | ||
| 
						 | 
					79d796a437 | ||
| 
						 | 
					cc2a458bce | ||
| 
						 | 
					a5ae67f93c | ||
| 
						 | 
					81c316efd1 | ||
| 
						 | 
					46a28543b9 | ||
| 
						 | 
					f142710fee | ||
| 
						 | 
					f1f903ef9f | ||
| 
						 | 
					d8a03bb34b | ||
| 
						 | 
					871651c0c1 | ||
| 
						 | 
					9647973983 | ||
| 
						 | 
					117e2fecf9 | ||
| 
						 | 
					a307d7d5c1 | ||
| 
						 | 
					a8131c2be2 | ||
| 
						 | 
					bf77a94721 | ||
| 
						 | 
					5670c459ca | ||
| 
						 | 
					672cbc3d1a | ||
| 
						 | 
					a3518e88d3 | ||
| 
						 | 
					56fafb8769 | ||
| 
						 | 
					40b7274c85 | ||
| 
						 | 
					61ce22338a | ||
| 
						 | 
					93a24b65a9 | ||
| 
						 | 
					b022555198 | ||
| 
						 | 
					2ea11d4d63 | ||
| 
						 | 
					152895b48c | ||
| 
						 | 
					bca38907e6 | ||
| 
						 | 
					8b29acfc59 | ||
| 
						 | 
					8c8f2a14b6 | ||
| 
						 | 
					859569e156 | ||
| 
						 | 
					9c3f576cd2 | ||
| 
						 | 
					a45f6a316e | ||
| 
						 | 
					bd3a1c5e2e | ||
| 
						 | 
					2ae02bedf8 | ||
| 
						 | 
					5ef1af5aef | ||
| 
						 | 
					8f72d2541f | ||
| 
						 | 
					5c95bc49af | ||
| 
						 | 
					1ee2a2a364 | ||
| 
						 | 
					a4afddc4e1 | ||
| 
						 | 
					6fd1c90f23 | ||
| 
						 | 
					7a00a68ab4 | ||
| 
						 | 
					d13561e1c7 | ||
| 
						 | 
					336a57fdf4 | ||
| 
						 | 
					26a9ca7a86 | ||
| 
						 | 
					cbb01f70e7 | ||
| 
						 | 
					089d3086cc | ||
| 
						 | 
					1b96832bf7 | ||
| 
						 | 
					5a10c58c35 | ||
| 
						 | 
					596113c80f | ||
| 
						 | 
					703cbb7bf3 | ||
| 
						 | 
					f31056faae | ||
| 
						 | 
					db20b79ac0 | ||
| 
						 | 
					3344bf9439 | ||
| 
						 | 
					2b7cc8088d | ||
| 
						 | 
					831cfb57b4 | ||
| 
						 | 
					f2ba0929d7 | ||
| 
						 | 
					5c87452b67 | ||
| 
						 | 
					f75b599e2a | ||
| 
						 | 
					b00a2ede79 | ||
| 
						 | 
					9def0cb66f | ||
| 
						 | 
					ddf65a2437 | ||
| 
						 | 
					4ced8279c6 | ||
| 
						 | 
					625693ac50 | ||
| 
						 | 
					1821eb1b39 | ||
| 
						 | 
					d1664f3502 | ||
| 
						 | 
					6235e04ded | ||
| 
						 | 
					9191748d82 | ||
| 
						 | 
					26166e8f51 | ||
| 
						 | 
					f9f4c6f36e | ||
| 
						 | 
					f16da0fde7 | ||
| 
						 | 
					abdfeaa96c | ||
| 
						 | 
					7e737977cb | ||
| 
						 | 
					a741663b20 | ||
| 
						 | 
					c0672d11c6 | ||
| 
						 | 
					842b0925fe | ||
| 
						 | 
					90d159a868 | ||
| 
						 | 
					130d26ce0a | ||
| 
						 | 
					bef731b9b9 | ||
| 
						 | 
					b0bd6245fa | ||
| 
						 | 
					54e19af0c5 | ||
| 
						 | 
					0e9cf861f4 | ||
| 
						 | 
					7876cdc71a | ||
| 
						 | 
					065647154e | ||
| 
						 | 
					6558cd5150 | ||
| 
						 | 
					c939fbce96 | ||
| 
						 | 
					c34ee74d08 | ||
| 
						 | 
					66cc1a74ec | ||
| 
						 | 
					8de565f269 | ||
| 
						 | 
					c3f366ce9e | ||
| 
						 | 
					7a262362df | ||
| 
						 | 
					9a4d992778 | ||
| 
						 | 
					fb3112b75d | ||
| 
						 | 
					3540121449 | ||
| 
						 | 
					a422fd80d9 | ||
| 
						 | 
					6cbf2d7e32 | ||
| 
						 | 
					40527ffd4e | ||
| 
						 | 
					eb242168bf | ||
| 
						 | 
					cfb8ef9f65 | ||
| 
						 | 
					a988298a65 | ||
| 
						 | 
					78e216fedb | ||
| 
						 | 
					115f493676 | ||
| 
						 | 
					e9f011b686 | ||
| 
						 | 
					8c873e0f49 | ||
| 
						 | 
					af045ab8b2 | ||
| 
						 | 
					42386c520d | ||
| 
						 | 
					fd56b5bdc4 | ||
| 
						 | 
					be54cd24de | ||
| 
						 | 
					ba96f7ddc2 | ||
| 
						 | 
					8a43ed99ed | ||
| 
						 | 
					84c0da2186 | ||
| 
						 | 
					d52d1bfeee | ||
| 
						 | 
					73628b13ea | ||
| 
						 | 
					8cefb59efb | ||
| 
						 | 
					908928b41c | ||
| 
						 | 
					97cbebc0f7 | ||
| 
						 | 
					04e93f513c | ||
| 
						 | 
					eef3bb19d3 | ||
| 
						 | 
					64eed3a40c | ||
| 
						 | 
					10da2c257d | ||
| 
						 | 
					c49d520d3d | ||
| 
						 | 
					650bddae63 | ||
| 
						 | 
					250678627a | ||
| 
						 | 
					56e37d0abb | ||
| 
						 | 
					bb0a2d3bd4 | ||
| 
						 | 
					eccfdbd986 | ||
| 
						 | 
					3360ad612e | ||
| 
						 | 
					fb620464d7 | ||
| 
						 | 
					ab813b607f | ||
| 
						 | 
					0e6d70c395 | ||
| 
						 | 
					27c187084b | ||
| 
						 | 
					781ced1a59 | ||
| 
						 | 
					8f3ac6e00b | ||
| 
						 | 
					24652abe8a | ||
| 
						 | 
					6e950cf49c | ||
| 
						 | 
					4935da8fe4 | ||
| 
						 | 
					170a5a8697 | ||
| 
						 | 
					18a3092aa1 | ||
| 
						 | 
					d7e35d2ad2 | ||
| 
						 | 
					f53f83be56 | ||
| 
						 | 
					42f4cdd40c | ||
| 
						 | 
					f5891e1c8c | ||
| 
						 | 
					2322f12b59 | ||
| 
						 | 
					c03850a302 | ||
| 
						 | 
					66002f375c | ||
| 
						 | 
					3d901637d1 | ||
| 
						 | 
					a7b3ccf198 | ||
| 
						 | 
					f8a845d996 | ||
| 
						 | 
					273941f451 | ||
| 
						 | 
					010ab08384 | ||
| 
						 | 
					2d9d65f33c | ||
| 
						 | 
					b4c23b8b70 | ||
| 
						 | 
					6a9d9700d4 | ||
| 
						 | 
					0688c7f4e7 | ||
| 
						 | 
					f42f2514cb | ||
| 
						 | 
					09ed07b0c8 | ||
| 
						 | 
					f30d568f10 | ||
| 
						 | 
					0c79418393 | ||
| 
						 | 
					b0f86d9fb6 | ||
| 
						 | 
					3b08ace966 | ||
| 
						 | 
					ee848e2367 | ||
| 
						 | 
					9d593a2a90 | ||
| 
						 | 
					208e7736e6 | ||
| 
						 | 
					bb05deca33 | ||
| 
						 | 
					cdbc7fffca | ||
| 
						 | 
					d797aea311 | ||
| 
						 | 
					873d5e3522 | ||
| 
						 | 
					ef4980448a | ||
| 
						 | 
					1c7c0b9af8 | ||
| 
						 | 
					5a14c3c76f | ||
| 
						 | 
					c826e8e78a | ||
| 
						 | 
					96fb97d53a | ||
| 
						 | 
					20d96f9ea3 | ||
| 
						 | 
					36df20eb0e | ||
| 
						 | 
					86d3932a16 | ||
| 
						 | 
					784f591dee | ||
| 
						 | 
					e80764a01e | ||
| 
						 | 
					3b9aa272f7 | ||
| 
						 | 
					1d1aff5622 | ||
| 
						 | 
					464a9ac503 | ||
| 
						 | 
					136ec3df58 | ||
| 
						 | 
					d9b4562076 | ||
| 
						 | 
					3a0b75a006 | ||
| 
						 | 
					6dbf9de06e | ||
| 
						 | 
					795256cba5 | ||
| 
						 | 
					b11ee3abc5 | ||
| 
						 | 
					82b19a6314 | ||
| 
						 | 
					18626901d3 | ||
| 
						 | 
					40d8e1e0f6 | ||
| 
						 | 
					b8b7b10bfd | ||
| 
						 | 
					ed5149c17f | ||
| 
						 | 
					f4fb495488 | ||
| 
						 | 
					b7dcf55d4c | ||
| 
						 | 
					7f7e4aa1ae | ||
| 
						 | 
					79db04dc2e | ||
| 
						 | 
					2478570deb | ||
| 
						 | 
					d80661211c | ||
| 
						 | 
					4420120b55 | ||
| 
						 | 
					1f237cd373 | ||
| 
						 | 
					214522f42a | ||
| 
						 | 
					0257c9d31e | ||
| 
						 | 
					e4729b8dc3 | ||
| 
						 | 
					5f55f14f9d | ||
| 
						 | 
					0809dc65ec | ||
| 
						 | 
					2696bd5b44 | ||
| 
						 | 
					9cfbb4106b | ||
| 
						 | 
					8461571fbd | ||
| 
						 | 
					700f2a6af3 | ||
| 
						 | 
					2f3fb4a387 | ||
| 
						 | 
					57d978b82d | ||
| 
						 | 
					7ccd7aa4e5 | ||
| 
						 | 
					42f9f07a07 | ||
| 
						 | 
					9f91b50553 | ||
| 
						 | 
					f8dd3ea133 | ||
| 
						 | 
					0fd0e9a1af | ||
| 
						 | 
					26751f2acd | ||
| 
						 | 
					849b831ca4 | ||
| 
						 | 
					4d10629acf | ||
| 
						 | 
					341fecd3ff | ||
| 
						 | 
					056a5c29cb | ||
| 
						 | 
					a20ab6f0c6 | ||
| 
						 | 
					70b83f5ca6 | ||
| 
						 | 
					9ca763127d | ||
| 
						 | 
					9fdae8c76f | ||
| 
						 | 
					8b44eef002 | ||
| 
						 | 
					e6960ceec1 | ||
| 
						 | 
					0141e681df | ||
| 
						 | 
					f5c58c8065 | ||
| 
						 | 
					3645f99259 | ||
| 
						 | 
					105159a285 | ||
| 
						 | 
					f958a3c2f7 | ||
| 
						 | 
					d4a776e759 | ||
| 
						 | 
					1ae79fe58c | ||
| 
						 | 
					687d44859f | ||
| 
						 | 
					2c07463ac6 | ||
| 
						 | 
					7356961f52 | ||
| 
						 | 
					e6d72cb23b | ||
| 
						 | 
					dc699db5f5 | ||
| 
						 | 
					c9be4c744f | ||
| 
						 | 
					916b87e62e | ||
| 
						 | 
					425901fb98 | ||
| 
						 | 
					3b55b65a34 | ||
| 
						 | 
					b763087e11 | ||
| 
						 | 
					e27c57f8a6 | ||
| 
						 | 
					821a62ffbb | ||
| 
						 | 
					72240d0d59 | ||
| 
						 | 
					13153df484 | ||
| 
						 | 
					fb910d7c41 | ||
| 
						 | 
					55f1df9563 | ||
| 
						 | 
					b2f1a28504 | ||
| 
						 | 
					aca48bc027 | ||
| 
						 | 
					753ba765eb | ||
| 
						 | 
					34d8d90688 | ||
| 
						 | 
					729c31dd7a | ||
| 
						 | 
					1b2d12b9a1 | ||
| 
						 | 
					ce74d2fdfc | ||
| 
						 | 
					d34f593562 | ||
| 
						 | 
					00898b18d6 | ||
| 
						 | 
					84186babab | ||
| 
						 | 
					18363ca183 | ||
| 
						 | 
					006c3f99e6 | ||
| 
						 | 
					04121892cf | ||
| 
						 | 
					3e72635204 | ||
| 
						 | 
					7dc450edb4 | ||
| 
						 | 
					6e8d820737 | ||
| 
						 | 
					135fce77c1 | ||
| 
						 | 
					b5c5eecdbd | ||
| 
						 | 
					af813ac95b | ||
| 
						 | 
					bb395db9f4 | ||
| 
						 | 
					ff7ceb2e2b | ||
| 
						 | 
					cada0f2547 | ||
| 
						 | 
					f4e5e08aa8 | ||
| 
						 | 
					5526cdc03c | ||
| 
						 | 
					63ee982d36 | ||
| 
						 | 
					4e5078c950 | ||
| 
						 | 
					61c67f8c22 | ||
| 
						 | 
					badb1d4706 | ||
| 
						 | 
					dfffbc62bc | ||
| 
						 | 
					fd53c090f4 | ||
| 
						 | 
					6de880c95d | ||
| 
						 | 
					de03a92a8f | ||
| 
						 | 
					2a7cbd2520 | ||
| 
						 | 
					4edad4d8c4 | ||
| 
						 | 
					7e4fc3e4c7 | ||
| 
						 | 
					f9f18e5d3b | ||
| 
						 | 
					4a852facb3 | ||
| 
						 | 
					09255a1d9c | ||
| 
						 | 
					f8345a09a2 | ||
| 
						 | 
					72f25f24ef | ||
| 
						 | 
					8466d1eb3e | ||
| 
						 | 
					cc7fe7fff7 | ||
| 
						 | 
					0a4e6804c6 | ||
| 
						 | 
					900700b9bc | ||
| 
						 | 
					12b62980cb | ||
| 
						 | 
					e7f6ead038 | ||
| 
						 | 
					51e3ac0ded | ||
| 
						 | 
					2a42084af4 | ||
| 
						 | 
					66682b3e84 | ||
| 
						 | 
					17814410e9 | ||
| 
						 | 
					cebafcf869 | ||
| 
						 | 
					7d5a4eafa2 | ||
| 
						 | 
					fc8e5fb5c7 | ||
| 
						 | 
					f352740aba | ||
| 
						 | 
					874a0c1f38 | ||
| 
						 | 
					8fea6f71ab | ||
| 
						 | 
					56071c4016 | ||
| 
						 | 
					9e664d7165 | ||
| 
						 | 
					cf5f0e1caa | ||
| 
						 | 
					62f3055e5a | ||
| 
						 | 
					542aa5c083 | ||
| 
						 | 
					9e2728bcb7 | ||
| 
						 | 
					6bf710bed3 | ||
| 
						 | 
					67ad12c2d0 | ||
| 
						 | 
					4a4d872bb0 | ||
| 
						 | 
					9d6bb2ee2a | ||
| 
						 | 
					a63c474d93 | ||
| 
						 | 
					f67df577db | ||
| 
						 | 
					25a6a5ee53 | ||
| 
						 | 
					cd4b8d4179 | ||
| 
						 | 
					31c8123677 | ||
| 
						 | 
					d318778f53 | ||
| 
						 | 
					152f99fb07 | ||
| 
						 | 
					42841a217c | ||
| 
						 | 
					7937cd625d | ||
| 
						 | 
					0d3e5e1c26 | ||
| 
						 | 
					52e2c8c262 | ||
| 
						 | 
					a9df841770 | ||
| 
						 | 
					7096ee760e | ||
| 
						 | 
					880c367d64 | ||
| 
						 | 
					704e250664 | ||
| 
						 | 
					928b46f18e | ||
| 
						 | 
					f42924a9ca | ||
| 
						 | 
					9196f696ea | ||
| 
						 | 
					824d706a20 | ||
| 
						 | 
					f4e9b3689d | ||
| 
						 | 
					bbeba5c9ab | ||
| 
						 | 
					0678957def | ||
| 
						 | 
					bc98b9892c | ||
| 
						 | 
					d0db56e964 | ||
| 
						 | 
					ef9bf2650c | ||
| 
						 | 
					7473462125 | ||
| 
						 | 
					40c5ef1c35 | ||
| 
						 | 
					fe04ae3ac1 | ||
| 
						 | 
					1bf5206bd7 | ||
| 
						 | 
					85c67113b7 | ||
| 
						 | 
					14129fedb6 | ||
| 
						 | 
					3bc3b352d8 | ||
| 
						 | 
					21aa608ce2 | ||
| 
						 | 
					091eb9683b | ||
| 
						 | 
					4be25e2f70 | ||
| 
						 | 
					2de7736291 | ||
| 
						 | 
					e005b1af32 | ||
| 
						 | 
					a8857e51f4 | ||
| 
						 | 
					ed9155bfd8 | ||
| 
						 | 
					4713f0be42 | ||
| 
						 | 
					8407d39109 | ||
| 
						 | 
					1f7b2a3d2d | ||
| 
						 | 
					a7cf1b18ce | ||
| 
						 | 
					f26ff07046 | ||
| 
						 | 
					fee8ac67ef | ||
| 
						 | 
					03ddabae16 | ||
| 
						 | 
					7e560fb40d | ||
| 
						 | 
					42e7fed10a | ||
| 
						 | 
					8aa8597ab0 | ||
| 
						 | 
					792c4914b0 | ||
| 
						 | 
					5307976179 | ||
| 
						 | 
					0bb93f4a97 | ||
| 
						 | 
					1c3817ad65 | ||
| 
						 | 
					a7d3630e42 | ||
| 
						 | 
					992d2d3be0 | ||
| 
						 | 
					ee1232b10a | ||
| 
						 | 
					1ef2fff03e | ||
| 
						 | 
					ade0fc7e19 | ||
| 
						 | 
					b80fde365b | ||
| 
						 | 
					01cec2e361 | ||
| 
						 | 
					f302bd8854 | ||
| 
						 | 
					6ef243ba37 | ||
| 
						 | 
					5bff26e1e0 | ||
| 
						 | 
					eefe65ad0e | ||
| 
						 | 
					c48209a9dd | ||
| 
						 | 
					d7459e2bfe | ||
| 
						 | 
					53926b8bbe | ||
| 
						 | 
					5e80dddc82 | ||
| 
						 | 
					585d06494e | ||
| 
						 | 
					62de4eb8bf | ||
| 
						 | 
					ab0a33ceae | ||
| 
						 | 
					e15e57600e | ||
| 
						 | 
					d02afa20b8 | ||
| 
						 | 
					d70d1ebfcd | ||
| 
						 | 
					eb5be9cd34 | ||
| 
						 | 
					cab4be1bd0 | ||
| 
						 | 
					78067110c9 | ||
| 
						 | 
					287e89e760 | ||
| 
						 | 
					1aee8401db | ||
| 
						 | 
					bbb0efc15e | ||
| 
						 | 
					70911b9275 | ||
| 
						 | 
					34ea3112a5 | ||
| 
						 | 
					4613386863 | ||
| 
						 | 
					4466e360e1 | ||
| 
						 | 
					1752dd573b | ||
| 
						 | 
					19af46faea | ||
| 
						 | 
					466c01b524 | ||
| 
						 | 
					9374daca64 | ||
| 
						 | 
					33fabccc14 | ||
| 
						 | 
					fae515c3a2 | ||
| 
						 | 
					2114a6f880 | ||
| 
						 | 
					29733819f5 | ||
| 
						 | 
					5d1b024237 | ||
| 
						 | 
					a3bd0d8091 | ||
| 
						 | 
					03f755d168 | ||
| 
						 | 
					1c49648fc5 | ||
| 
						 | 
					a86f3ba96d | ||
| 
						 | 
					c86ff3a5bb | ||
| 
						 | 
					ab8d59bd41 | ||
| 
						 | 
					dcbb83ebe5 | ||
| 
						 | 
					807dee54fd | ||
| 
						 | 
					73d09977fc | ||
| 
						 | 
					47016765b3 | ||
| 
						 | 
					217e4ab4f7 | ||
| 
						 | 
					b129cb0786 | ||
| 
						 | 
					e102e2630e | ||
| 
						 | 
					7650795f48 | ||
| 
						 | 
					e5036da084 | ||
| 
						 | 
					07f4ec529b | ||
| 
						 | 
					0b2af86ec9 | ||
| 
						 | 
					8b917ace4d | ||
| 
						 | 
					ab1c78ca23 | ||
| 
						 | 
					3679bb45f0 | ||
| 
						 | 
					1101b0dc82 | ||
| 
						 | 
					15b4660d3e | ||
| 
						 | 
					e457d099d8 | ||
| 
						 | 
					7686b89cd6 | ||
| 
						 | 
					e757639669 | ||
| 
						 | 
					7b22546b14 | ||
| 
						 | 
					7db14cb5cf | ||
| 
						 | 
					33b4fd3a20 | ||
| 
						 | 
					c8185affb9 | ||
| 
						 | 
					91e1087eb9 | ||
| 
						 | 
					24026af32a | ||
| 
						 | 
					2241445b09 | ||
| 
						 | 
					fb893542a2 | ||
| 
						 | 
					9a66b51117 | ||
| 
						 | 
					caa15c03a6 | ||
| 
						 | 
					87ff7ae0da | ||
| 
						 | 
					58306de28a | ||
| 
						 | 
					56c27c4255 | ||
| 
						 | 
					9084d746af | ||
| 
						 | 
					18fef8dfe5 | ||
| 
						 | 
					7e5df42fc0 | ||
| 
						 | 
					e11a0ee448 | ||
| 
						 | 
					18f8633dd9 | ||
| 
						 | 
					497422e72c | ||
| 
						 | 
					78a8993f38 | ||
| 
						 | 
					1f7dd2fcd5 | ||
| 
						 | 
					2ccd59e90b | ||
| 
						 | 
					3bd610a838 | ||
| 
						 | 
					5060a66d4e | ||
| 
						 | 
					3c5ac535f1 | ||
| 
						 | 
					82d721f455 | ||
| 
						 | 
					bef6b2fffd | ||
| 
						 | 
					fac8662387 | ||
| 
						 | 
					15dc47555a | ||
| 
						 | 
					171a597355 | ||
| 
						 | 
					022f04355a | ||
| 
						 | 
					9786614917 | ||
| 
						 | 
					e351b1dafa | ||
| 
						 | 
					075185547a | ||
| 
						 | 
					514b728449 | ||
| 
						 | 
					9a3d9feb30 | ||
| 
						 | 
					fcb893cd12 | ||
| 
						 | 
					e79f29dc0e | ||
| 
						 | 
					11d7870d68 | ||
| 
						 | 
					fc653adcc0 | ||
| 
						 | 
					ee925492d4 | ||
| 
						 | 
					6348309936 | ||
| 
						 | 
					a9e098b0b4 | ||
| 
						 | 
					8f5c3fa302 | ||
| 
						 | 
					cbd4bd9bbe | ||
| 
						 | 
					f4117881cd | ||
| 
						 | 
					69e00d181a | ||
| 
						 | 
					b0837b1a98 | ||
| 
						 | 
					a67adf7702 | ||
| 
						 | 
					f6b65b3b93 | ||
| 
						 | 
					bbea67ecb4 | ||
| 
						 | 
					cc3ab110ee | ||
| 
						 | 
					d76dd2f8e0 | ||
| 
						 | 
					334b7fc219 | ||
| 
						 | 
					f923dedc3f | ||
| 
						 | 
					576f244d2d | ||
| 
						 | 
					d03a8acc9d | ||
| 
						 | 
					2c0d9396e2 | ||
| 
						 | 
					bb278c7ba9 | ||
| 
						 | 
					3bf0a93b86 | ||
| 
						 | 
					82b5ca8bfc | ||
| 
						 | 
					baf8ef2c33 | ||
| 
						 | 
					913b7c8809 | ||
| 
						 | 
					7ccc5d08c8 | ||
| 
						 | 
					7f232f0994 | ||
| 
						 | 
					30139107de | ||
| 
						 | 
					9c58f49c49 | ||
| 
						 | 
					3b02115f8e | ||
| 
						 | 
					dad12a0e02 | ||
| 
						 | 
					c28ba5ffb2 | ||
| 
						 | 
					9ca6d3c715 | ||
| 
						 | 
					b95eb55994 | ||
| 
						 | 
					1a8fc1feec | ||
| 
						 | 
					92b1341730 | ||
| 
						 | 
					3524d4a0d0 | ||
| 
						 | 
					3b0aa69ad3 | ||
| 
						 | 
					9299bedd7e | ||
| 
						 | 
					a12c6de2ef | ||
| 
						 | 
					2f78a37426 | ||
| 
						 | 
					c5c546d290 | ||
| 
						 | 
					854c711ac6 | ||
| 
						 | 
					6a6aa8867b | ||
| 
						 | 
					b653b13002 | ||
| 
						 | 
					99bf5497ca | ||
| 
						 | 
					73462d9214 | ||
| 
						 | 
					8a8ac4fe2b | ||
| 
						 | 
					4494a4b35a | ||
| 
						 | 
					04f38ea661 | ||
| 
						 | 
					55dcd831bc | ||
| 
						 | 
					94d5746268 | ||
| 
						 | 
					b52b54849a | ||
| 
						 | 
					345830794a | ||
| 
						 | 
					c70deed13a | ||
| 
						 | 
					3381e3040c | ||
| 
						 | 
					8deead2781 | ||
| 
						 | 
					04a3ac5557 | ||
| 
						 | 
					5c2c60612b | ||
| 
						 | 
					14ef6577ae | ||
| 
						 | 
					1f289bc93d | ||
| 
						 | 
					511631c6ae | ||
| 
						 | 
					93be40349b | ||
| 
						 | 
					a45f324ed8 | ||
| 
						 | 
					9e4b2d14cb | ||
| 
						 | 
					ec3282e15d | ||
| 
						 | 
					9b769f0ae4 | ||
| 
						 | 
					e51a47d072 | ||
| 
						 | 
					f64938cb3f | ||
| 
						 | 
					9b0ef5fce5 | ||
| 
						 | 
					8ce92d450c | ||
| 
						 | 
					982f9c8458 | ||
| 
						 | 
					f888cb87d1 | ||
| 
						 | 
					97031ea3e6 | ||
| 
						 | 
					a303efb174 | ||
| 
						 | 
					029bb3efdd | ||
| 
						 | 
					4545470f2d | ||
| 
						 | 
					99b19b9539 | ||
| 
						 | 
					aedb55ea36 | ||
| 
						 | 
					49c56add7d | ||
| 
						 | 
					930d8e20ff | ||
| 
						 | 
					8ec02b3d16 | ||
| 
						 | 
					bb62bebf1a | ||
| 
						 | 
					ce8aaf8955 | ||
| 
						 | 
					db3160145e | ||
| 
						 | 
					7c5a663237 | ||
| 
						 | 
					6f28120401 | ||
| 
						 | 
					1ee82e390b | ||
| 
						 | 
					88d392f612 | ||
| 
						 | 
					9b651b4f00 | ||
| 
						 | 
					f4a10a313c | ||
| 
						 | 
					7d89643146 | ||
| 
						 | 
					276aa191d5 | ||
| 
						 | 
					fa28999561 | ||
| 
						 | 
					121b11525f | ||
| 
						 | 
					b2aa5d8dea | ||
| 
						 | 
					b44091b4e3 | ||
| 
						 | 
					05468016a1 | ||
| 
						 | 
					f0d4788e6d | ||
| 
						 | 
					28bf8478c4 | ||
| 
						 | 
					d998c9e24b | ||
| 
						 | 
					26a613fff1 | ||
| 
						 | 
					1a3f41ff33 | ||
| 
						 | 
					d5e0fca490 | ||
| 
						 | 
					87c8c3e6ee | ||
| 
						 | 
					d8e49cd9e7 | ||
| 
						 | 
					20c44ff99a | ||
| 
						 | 
					1a6fb1c3d2 | ||
| 
						 | 
					d89955f4b3 | ||
| 
						 | 
					743d3ecd01 | ||
| 
						 | 
					f60def5ecc | ||
| 
						 | 
					c35da331a2 | ||
| 
						 | 
					4b905d5b52 | ||
| 
						 | 
					b5faf1be9b | ||
| 
						 | 
					ea061ae239 | ||
| 
						 | 
					9e522eddf8 | ||
| 
						 | 
					923379def6 | ||
| 
						 | 
					53d3fcb2fd | ||
| 
						 | 
					a6afb6be7c | ||
| 
						 | 
					0f84efed39 | ||
| 
						 | 
					6596cd1208 | ||
| 
						 | 
					207576c885 | ||
| 
						 | 
					667e88f2df | ||
| 
						 | 
					569db7c018 | ||
| 
						 | 
					dca5d9b52b | ||
| 
						 | 
					827d06df85 | ||
| 
						 | 
					107afcff27 | ||
| 
						 | 
					1793c627cd | ||
| 
						 | 
					7aafeec2cb | ||
| 
						 | 
					2f782f18c4 | ||
| 
						 | 
					53c4bbe4e0 | ||
| 
						 | 
					4fe55533d7 | ||
| 
						 | 
					9b3bc3d25f | ||
| 
						 | 
					60630efa6a | ||
| 
						 | 
					7e51731167 | ||
| 
						 | 
					c5fec83f64 | ||
| 
						 | 
					f2a6736883 | ||
| 
						 | 
					5b40f17b9c | ||
| 
						 | 
					d4812bbb36 | ||
| 
						 | 
					e3515347ed | ||
| 
						 | 
					03b261dfc5 | ||
| 
						 | 
					05991c9ee9 | ||
| 
						 | 
					9779676fd8 | ||
| 
						 | 
					77190a0d42 | ||
| 
						 | 
					c3224e60d6 | ||
| 
						 | 
					aecdb5fe6d | ||
| 
						 | 
					c1f1934c27 | ||
| 
						 | 
					23f501c071 | ||
| 
						 | 
					92f4ab30ea | ||
| 
						 | 
					682ae24b7d | ||
| 
						 | 
					7129a2239c | ||
| 
						 | 
					9dd2f275f1 | ||
| 
						 | 
					f04f0a7e1d | ||
| 
						 | 
					99d11f754f | ||
| 
						 | 
					62888f7984 | ||
| 
						 | 
					240c89c585 | ||
| 
						 | 
					b1742876fd | ||
| 
						 | 
					f34008b518 | ||
| 
						 | 
					03291fb726 | ||
| 
						 | 
					0be88f1453 | ||
| 
						 | 
					a59c45d869 | ||
| 
						 | 
					7f14aa6bf1 | ||
| 
						 | 
					c7cc599a19 | ||
| 
						 | 
					3b55c2805a | ||
| 
						 | 
					cf097850de | ||
| 
						 | 
					b167d8da03 | ||
| 
						 | 
					e507a23795 | ||
| 
						 | 
					5160fdc26a | ||
| 
						 | 
					8f769006d6 | ||
| 
						 | 
					9f6f82405b | ||
| 
						 | 
					932ab17c9a | ||
| 
						 | 
					ebdcb15703 | ||
| 
						 | 
					660b198da0 | ||
| 
						 | 
					fa7394723c | ||
| 
						 | 
					3ea25a901e | ||
| 
						 | 
					d5c6a70442 | ||
| 
						 | 
					0fff01e36e | ||
| 
						 | 
					95240da872 | ||
| 
						 | 
					93e7b12a5d | ||
| 
						 | 
					4b3b44bdfb | ||
| 
						 | 
					d98027ad2f | ||
| 
						 | 
					2bf43ffbf2 | ||
| 
						 | 
					0c7f06137a | ||
| 
						 | 
					a352bd946e | ||
| 
						 | 
					d1e4740e70 | ||
| 
						 | 
					baad8f7d2c | ||
| 
						 | 
					5d23a8f693 | ||
| 
						 | 
					9127b76e5f | ||
| 
						 | 
					aede7056f2 | ||
| 
						 | 
					cf913b87ff | ||
| 
						 | 
					c4eee7bb11 | ||
| 
						 | 
					7f90b99388 | ||
| 
						 | 
					f4720ae02c | ||
| 
						 | 
					45fff23499 | ||
| 
						 | 
					82dcc1b57b | ||
| 
						 | 
					d8be9a9443 | ||
| 
						 | 
					fbcd1ffbbe | ||
| 
						 | 
					d8c875f351 | ||
| 
						 | 
					6f738813a6 | ||
| 
						 | 
					4a30aae9bb | ||
| 
						 | 
					691951974d | ||
| 
						 | 
					e9899d0345 | ||
| 
						 | 
					ffeab32403 | ||
| 
						 | 
					80300e412c | ||
| 
						 | 
					51f67f6c3e | ||
| 
						 | 
					cf2899b1e6 | ||
| 
						 | 
					c0f4b80cbe | ||
| 
						 | 
					19afa46978 | ||
| 
						 | 
					6a2e80a0b7 | ||
| 
						 | 
					5b994f85c9 | ||
| 
						 | 
					f7d4f049a7 | ||
| 
						 | 
					37e189992e | ||
| 
						 | 
					c1a01ca7a6 | ||
| 
						 | 
					e597998021 | ||
| 
						 | 
					f65feedcce | ||
| 
						 | 
					6be1208488 | ||
| 
						 | 
					63ed2e5fb8 | ||
| 
						 | 
					22c9d888b4 | ||
| 
						 | 
					1db217931b | ||
| 
						 | 
					a657d7388c | ||
| 
						 | 
					f4c2db7f21 | ||
| 
						 | 
					95122fdcf5 | ||
| 
						 | 
					2aa8c2f0e0 | ||
| 
						 | 
					88afcee37a | ||
| 
						 | 
					929496552e | ||
| 
						 | 
					c9156d41b1 | ||
| 
						 | 
					7a462f4522 | ||
| 
						 | 
					ed5c4c9c87 | ||
| 
						 | 
					b4b7deac2d | ||
| 
						 | 
					d1866edfe5 | ||
| 
						 | 
					79683dd83d | ||
| 
						 | 
					c587145bdd | ||
| 
						 | 
					4d5ae96db6 | ||
| 
						 | 
					6034feb69d | ||
| 
						 | 
					afa5e75d76 | ||
| 
						 | 
					5e4866c439 | ||
| 
						 | 
					0070dd2c01 | ||
| 
						 | 
					4c5ee3b53a | ||
| 
						 | 
					5d6375dab7 | ||
| 
						 | 
					546780d7a8 | ||
| 
						 | 
					ac083f787d | ||
| 
						 | 
					bca4b73677 | ||
| 
						 | 
					da2612d2d9 | ||
| 
						 | 
					08cd79f0c2 | ||
| 
						 | 
					4811c59e33 | ||
| 
						 | 
					11f3f938d8 | ||
| 
						 | 
					85a3d1dc84 | ||
| 
						 | 
					6101dd9079 | ||
| 
						 | 
					79a91b486a | ||
| 
						 | 
					2aaaabe152 | ||
| 
						 | 
					a93126a6d0 | ||
| 
						 | 
					112d0b2e90 | ||
| 
						 | 
					98bbc222cb | ||
| 
						 | 
					fad23c9ac6 | ||
| 
						 | 
					e6813949af | ||
| 
						 | 
					4be932ff9d | ||
| 
						 | 
					8eb7eb8b1f | ||
| 
						 | 
					b4ac6b73c8 | ||
| 
						 | 
					2eda55d3af | ||
| 
						 | 
					a8f6596d38 | ||
| 
						 | 
					b227419f01 | ||
| 
						 | 
					da03e12b7b | ||
| 
						 | 
					f349a9c864 | ||
| 
						 | 
					624bb13736 | ||
| 
						 | 
					94bca61491 | ||
| 
						 | 
					ee2fea74df | ||
| 
						 | 
					1f9ae6cae6 | ||
| 
						 | 
					e14fa5de75 | ||
| 
						 | 
					626ab98949 | ||
| 
						 | 
					3be6946d93 | ||
| 
						 | 
					475c0d21a1 | ||
| 
						 | 
					c2ae5fad96 | ||
| 
						 | 
					4fe5f1c06f | ||
| 
						 | 
					5b483ab26f | ||
| 
						 | 
					3e1bc6cb22 | ||
| 
						 | 
					bb1d3022e0 | ||
| 
						 | 
					a50ffa74e1 | ||
| 
						 | 
					03f2e45605 | ||
| 
						 | 
					4e61f24960 | ||
| 
						 | 
					1c853941dc | ||
| 
						 | 
					24a881ad75 | ||
| 
						 | 
					7cfa654a68 | ||
| 
						 | 
					7864ab5cfa | ||
| 
						 | 
					905f1241e3 | ||
| 
						 | 
					f0aba5db96 | ||
| 
						 | 
					480fe56ae3 | ||
| 
						 | 
					728315d3cc | ||
| 
						 | 
					da72e815dc | ||
| 
						 | 
					0145f6fe7d | ||
| 
						 | 
					cfeba736d5 | ||
| 
						 | 
					be18e51bc9 | ||
| 
						 | 
					7fc2859f23 | ||
| 
						 | 
					587a18a6fa | ||
| 
						 | 
					043619cd4b | ||
| 
						 | 
					f04394d014 | ||
| 
						 | 
					07354a26a9 | ||
| 
						 | 
					fdf0f208f0 | ||
| 
						 | 
					6680584724 | ||
| 
						 | 
					c5573a1997 | ||
| 
						 | 
					b8ce21d572 | ||
| 
						 | 
					1356012fb4 | ||
| 
						 | 
					8bb2c5fc6b | ||
| 
						 | 
					dc7a1e43b7 | ||
| 
						 | 
					53c90516b2 | ||
| 
						 | 
					d3ed5663d0 | ||
| 
						 | 
					778c2855f4 | ||
| 
						 | 
					445ed870cc | ||
| 
						 | 
					3be52f8b37 | ||
| 
						 | 
					a1b7ba0dc5 | ||
| 
						 | 
					8b5e49d980 | ||
| 
						 | 
					90f6ea1fc8 | ||
| 
						 | 
					238672ef78 | ||
| 
						 | 
					b1ecbb4151 | ||
| 
						 | 
					795b2c88e8 | ||
| 
						 | 
					becb1d5710 | ||
| 
						 | 
					5b225cf960 | ||
| 
						 | 
					6261f8a5cb | ||
| 
						 | 
					132ebd2c2d | ||
| 
						 | 
					db86c24638 | ||
| 
						 | 
					03da766b39 | ||
| 
						 | 
					adaed52818 | ||
| 
						 | 
					7ac42b5f40 | ||
| 
						 | 
					3cdb019de7 | ||
| 
						 | 
					b4afedc79e | ||
| 
						 | 
					3870851074 | ||
| 
						 | 
					046a228d62 | ||
| 
						 | 
					2c20a00cc3 | ||
| 
						 | 
					45d6eb36fb | ||
| 
						 | 
					7ea21663ca | ||
| 
						 | 
					5ca029df25 | ||
| 
						 | 
					bc2713ccbb | ||
| 
						 | 
					bb948c47dc | ||
| 
						 | 
					fa29ae2c5e | ||
| 
						 | 
					043bdc36d6 | ||
| 
						 | 
					f0eb7ffbda | ||
| 
						 | 
					e8ca298712 | ||
| 
						 | 
					13700b18c8 | ||
| 
						 | 
					1197d8c750 | ||
| 
						 | 
					09f47b5762 | ||
| 
						 | 
					4611545f93 | ||
| 
						 | 
					6e715205d7 | ||
| 
						 | 
					09a03fbbc0 | ||
| 
						 | 
					bb3f4442f5 | ||
| 
						 | 
					5b05110351 | ||
| 
						 | 
					eda85c176a | ||
| 
						 | 
					32da51b44c | ||
| 
						 | 
					0b6239a996 | ||
| 
						 | 
					79ae3cd00f | ||
| 
						 | 
					c2e63f4a6b | ||
| 
						 | 
					8b804c4ae0 | ||
| 
						 | 
					3030a710cc | ||
| 
						 | 
					b07c9bb4af | ||
| 
						 | 
					3234de5753 | ||
| 
						 | 
					2f9edb3e08 | ||
| 
						 | 
					ca7f288488 | ||
| 
						 | 
					49890acd04 | ||
| 
						 | 
					dc11dd2203 | ||
| 
						 | 
					6e59177f54 | ||
| 
						 | 
					d2ac201b98 | ||
| 
						 | 
					c8ea3bccf7 | ||
| 
						 | 
					8e4c9b8bd6 | ||
| 
						 | 
					13196ed2e2 | ||
| 
						 | 
					eb2cf60466 | ||
| 
						 | 
					149f3ff3fe | ||
| 
						 | 
					d89553a777 | ||
| 
						 | 
					890c17cd71 | ||
| 
						 | 
					6ef7acc108 | ||
| 
						 | 
					baf8297cc4 | ||
| 
						 | 
					47f2dd3c18 | ||
| 
						 | 
					6e08da6c8d | ||
| 
						 | 
					b8c02587ae | ||
| 
						 | 
					aa332477fd | ||
| 
						 | 
					d9f7726f7d | ||
| 
						 | 
					2f2a418cc4 | ||
| 
						 | 
					2dd77ee828 | ||
| 
						 | 
					bfa7b9a792 | ||
| 
						 | 
					32c5e18db0 | ||
| 
						 | 
					003e7949e3 | ||
| 
						 | 
					e8936392e3 | ||
| 
						 | 
					c834a5066d | ||
| 
						 | 
					6bf0da7230 | ||
| 
						 | 
					1d96c5af46 | ||
| 
						 | 
					6e8779cbce | ||
| 
						 | 
					ceb9ec4115 | ||
| 
						 | 
					c22bbea528 | ||
| 
						 | 
					5277892e4f | ||
| 
						 | 
					5b767e147d | ||
| 
						 | 
					0178fe6782 | ||
| 
						 | 
					209c48d67f | ||
| 
						 | 
					310d67cf27 | ||
| 
						 | 
					f26c81700d | ||
| 
						 | 
					96ccf256b2 | ||
| 
						 | 
					951ddfb72a | ||
| 
						 | 
					e4a3b66024 | ||
| 
						 | 
					1667d75a70 | ||
| 
						 | 
					ce23efae99 | ||
| 
						 | 
					3845e05834 | ||
| 
						 | 
					7cea1cb56e | ||
| 
						 | 
					cdc3a9aad2 | ||
| 
						 | 
					86ec0a6bd2 | ||
| 
						 | 
					dfd13b4948 | ||
| 
						 | 
					28bd737062 | ||
| 
						 | 
					ec1b73be2b | ||
| 
						 | 
					864dcdb2c2 | ||
| 
						 | 
					61e0d538e9 | ||
| 
						 | 
					474aaf7603 | ||
| 
						 | 
					65488ca174 | ||
| 
						 | 
					1260d3fcb9 | ||
| 
						 | 
					3e0c9ba056 | ||
| 
						 | 
					fcbe8d3a3e | ||
| 
						 | 
					7f643010b2 | ||
| 
						 | 
					e9970474f5 | ||
| 
						 | 
					8a1e5d35fa | ||
| 
						 | 
					90459e434f | ||
| 
						 | 
					bd07db544f | ||
| 
						 | 
					6b838bbf3d | ||
| 
						 | 
					df3e049e1c | ||
| 
						 | 
					bb24ee1b3b | ||
| 
						 | 
					c80b4ff4c2 | ||
| 
						 | 
					596e471276 | ||
| 
						 | 
					e1e29780f2 | ||
| 
						 | 
					fa10bb8dd3 | ||
| 
						 | 
					01d55254f2 | ||
| 
						 | 
					180b12fbaf | ||
| 
						 | 
					dc8901113e | ||
| 
						 | 
					f947c072e1 | ||
| 
						 | 
					ee032b43fe | ||
| 
						 | 
					f37a775977 | ||
| 
						 | 
					855391b31d | ||
| 
						 | 
					8ca6a7caef | ||
| 
						 | 
					b0d951d7e5 | ||
| 
						 | 
					8233be93cf | ||
| 
						 | 
					8652fc5f6d | ||
| 
						 | 
					6792eb5191 | ||
| 
						 | 
					b00177bd65 | ||
| 
						 | 
					bcd8ebd614 | ||
| 
						 | 
					46c59be541 | ||
| 
						 | 
					2f2271aad6 | ||
| 
						 | 
					feba83acdd | ||
| 
						 | 
					f5b882a075 | ||
| 
						 | 
					b0f6530a58 | ||
| 
						 | 
					ece1e338e0 | ||
| 
						 | 
					e814920bca | ||
| 
						 | 
					c70e31a919 | ||
| 
						 | 
					7e17106f34 | ||
| 
						 | 
					9603cbef14 | ||
| 
						 | 
					87cca4053f | ||
| 
						 | 
					b65321d80b | ||
| 
						 | 
					18307d9f57 | ||
| 
						 | 
					3ee388526d | ||
| 
						 | 
					13cb84aa75 | ||
| 
						 | 
					efe84bc6c0 | ||
| 
						 | 
					5a4e2b73ab | ||
| 
						 | 
					152b3c333b | ||
| 
						 | 
					7b3c4db8f0 | ||
| 
						 | 
					7cc84b89be | ||
| 
						 | 
					4db4e983e3 | ||
| 
						 | 
					3aac4dea67 | ||
| 
						 | 
					0a7262148e | ||
| 
						 | 
					ec8bab4013 | ||
| 
						 | 
					4778d9b2dd | ||
| 
						 | 
					3a90382699 | ||
| 
						 | 
					3ebe695a23 | ||
| 
						 | 
					ebae698a6e | ||
| 
						 | 
					18ad188ef6 | ||
| 
						 | 
					6e440bf9bb | ||
| 
						 | 
					490ac8d086 | ||
| 
						 | 
					c48c91a5bd | ||
| 
						 | 
					ee99ee48f6 | ||
| 
						 | 
					a5b21b2500 | ||
| 
						 | 
					75c947c5a3 | ||
| 
						 | 
					1ccabf1b13 | ||
| 
						 | 
					6da9bad272 | ||
| 
						 | 
					074941e2bd | ||
| 
						 | 
					5d71723aec | ||
| 
						 | 
					de0bbbe90a | ||
| 
						 | 
					7f05096611 | ||
| 
						 | 
					7635b76352 | ||
| 
						 | 
					b9559a9d82 | ||
| 
						 | 
					76892136cf | ||
| 
						 | 
					11bf84bac7 | ||
| 
						 | 
					24a376493b | ||
| 
						 | 
					ca3f0e2892 | ||
| 
						 | 
					e861d8b319 | ||
| 
						 | 
					abb6f73725 | ||
| 
						 | 
					3dd02edc78 | ||
| 
						 | 
					d5bef9efb5 | ||
| 
						 | 
					5f7b221e11 | ||
| 
						 | 
					16a029abd2 | ||
| 
						 | 
					f3e85efd41 | ||
| 
						 | 
					2c186132cd | ||
| 
						 | 
					ce6aec158a | ||
| 
						 | 
					54fd81a87e | ||
| 
						 | 
					11424195ef | ||
| 
						 | 
					fad2f6ea88 | ||
| 
						 | 
					58cf9ffeeb | ||
| 
						 | 
					85f36c77b1 | ||
| 
						 | 
					138db1c817 | ||
| 
						 | 
					126838fe1d | ||
| 
						 | 
					f0958535df | ||
| 
						 | 
					d7865a5bcd | ||
| 
						 | 
					dd2e14853c | ||
| 
						 | 
					b0436bf050 | ||
| 
						 | 
					b6692341e7 | ||
| 
						 | 
					af4b87a4cc | ||
| 
						 | 
					c3524c07ad | ||
| 
						 | 
					cca38695ed | ||
| 
						 | 
					cf20d6495b | ||
| 
						 | 
					8bdfcac0fb | ||
| 
						 | 
					4bed079ebf | ||
| 
						 | 
					daa5731acf | ||
| 
						 | 
					9ef520f862 | ||
| 
						 | 
					0bef2a91a1 | ||
| 
						 | 
					4fb8993a38 | ||
| 
						 | 
					91762e3df4 | ||
| 
						 | 
					90452147a3 | ||
| 
						 | 
					8639c9a79f | ||
| 
						 | 
					7291656f19 | ||
| 
						 | 
					cd0785164b | ||
| 
						 | 
					bd4bed1438 | ||
| 
						 | 
					737ec690b6 | ||
| 
						 | 
					fa1b47a357 | ||
| 
						 | 
					2a86e86817 | ||
| 
						 | 
					06b6263c24 | ||
| 
						 | 
					e4b44b5f85 | ||
| 
						 | 
					4821f450f3 | ||
| 
						 | 
					575654941f | ||
| 
						 | 
					f62198e250 | ||
| 
						 | 
					be217c6a47 | ||
| 
						 | 
					0486e48c4e | ||
| 
						 | 
					2f145fcf44 | ||
| 
						 | 
					ead641c344 | ||
| 
						 | 
					24306efddb | ||
| 
						 | 
					0720d56803 | ||
| 
						 | 
					85a2160098 | ||
| 
						 | 
					858e271c8a | ||
| 
						 | 
					e3af4f3e26 | ||
| 
						 | 
					51a5c4de0f | ||
| 
						 | 
					7108d4a509 | ||
| 
						 | 
					69ef13ef0c | ||
| 
						 | 
					e24d14c512 | ||
| 
						 | 
					7faf4f30df | ||
| 
						 | 
					ac44aab74a | ||
| 
						 | 
					6130a9c51f | ||
| 
						 | 
					c79bb3cd10 | ||
| 
						 | 
					b9691c339e | ||
| 
						 | 
					5e6d292235 | ||
| 
						 | 
					faf1d68d32 | ||
| 
						 | 
					e8c11003e3 | ||
| 
						 | 
					94039c19bb | ||
| 
						 | 
					e8209089c6 | ||
| 
						 | 
					fe582fb94d | ||
| 
						 | 
					74d65d8338 | ||
| 
						 | 
					2800128a8d | ||
| 
						 | 
					3120abbce8 | ||
| 
						 | 
					e5323ec487 | ||
| 
						 | 
					f2142bc4b3 | ||
| 
						 | 
					dd7767dbc5 | ||
| 
						 | 
					f825d4fef2 | ||
| 
						 | 
					aaee088fab | ||
| 
						 | 
					a0cb4b63a8 | ||
| 
						 | 
					344948b5ab | ||
| 
						 | 
					2088502e57 | ||
| 
						 | 
					57c174c37f | ||
| 
						 | 
					5c82cb32ab | ||
| 
						 | 
					aa315c0696 | ||
| 
						 | 
					0a339a5402 | ||
| 
						 | 
					953b899f75 | ||
| 
						 | 
					870009e815 | ||
| 
						 | 
					89824a9e0d | ||
| 
						 | 
					24ca64deac | ||
| 
						 | 
					85debfc69b | ||
| 
						 | 
					f0104af1c3 | ||
| 
						 | 
					e5fa58b890 | ||
| 
						 | 
					0b943e801c | ||
| 
						 | 
					b9dac6eef8 | ||
| 
						 | 
					e0fdde06c9 | ||
| 
						 | 
					2de09d4001 | ||
| 
						 | 
					a9a287fa59 | ||
| 
						 | 
					b5dba9108c | ||
| 
						 | 
					7b45793b60 | ||
| 
						 | 
					1410157356 | ||
| 
						 | 
					0253977778 | ||
| 
						 | 
					ca4a187d1a | ||
| 
						 | 
					7fa02fd41c | ||
| 
						 | 
					2a1ec84c87 | ||
| 
						 | 
					04b119b051 | ||
| 
						 | 
					f49389a408 | ||
| 
						 | 
					c322eaa430 | ||
| 
						 | 
					e56158f5b4 | ||
| 
						 | 
					6c2b2b0daa | ||
| 
						 | 
					0c84a87c67 | ||
| 
						 | 
					105517fed7 | ||
| 
						 | 
					ac34cfadea | ||
| 
						 | 
					3e58639a68 | ||
| 
						 | 
					3f8078ea0f | ||
| 
						 | 
					218c1d9344 | ||
| 
						 | 
					0df288f647 | ||
| 
						 | 
					d0100afe02 | ||
| 
						 | 
					23f6b25cfc | ||
| 
						 | 
					2faa791de4 | ||
| 
						 | 
					8e959105c6 | ||
| 
						 | 
					dde55471ba | ||
| 
						 | 
					f3a7f6cdef | ||
| 
						 | 
					5e4028ec87 | ||
| 
						 | 
					cd56bab622 | ||
| 
						 | 
					13a2d25b24 | ||
| 
						 | 
					7f09cdca65 | ||
| 
						 | 
					e9083ecabb | ||
| 
						 | 
					7aaefa42d1 | ||
| 
						 | 
					9e1b8622f2 | ||
| 
						 | 
					65f5db29bb | ||
| 
						 | 
					07e831a5bf | ||
| 
						 | 
					5cea95d5eb | ||
| 
						 | 
					d3d4690a81 | ||
| 
						 | 
					ebf8d63669 | ||
| 
						 | 
					5701937883 | ||
| 
						 | 
					f7d8384bff | ||
| 
						 | 
					be513813e6 | ||
| 
						 | 
					24fbd3ab90 | ||
| 
						 | 
					96f3de12b3 | ||
| 
						 | 
					fbdb9e6779 | ||
| 
						 | 
					e5f5ef0d17 | ||
| 
						 | 
					a1699e28a2 | ||
| 
						 | 
					c2c55f03c9 | ||
| 
						 | 
					c90b9786c6 | ||
| 
						 | 
					b9a243028b | ||
| 
						 | 
					748b16ba7f | ||
| 
						 | 
					be398d7edb | ||
| 
						 | 
					d10a952065 | ||
| 
						 | 
					97ebaad81e | ||
| 
						 | 
					68ad34e421 | ||
| 
						 | 
					5f55784137 | ||
| 
						 | 
					e22efab1b3 | ||
| 
						 | 
					be47b5e59c | ||
| 
						 | 
					97eea9bde2 | ||
| 
						 | 
					d972dab9b7 | ||
| 
						 | 
					b5f8e30093 | ||
| 
						 | 
					9d9cd44617 | ||
| 
						 | 
					c1f7a2c855 | ||
| 
						 | 
					e0f40cb4a4 | ||
| 
						 | 
					04e927e67f | ||
| 
						 | 
					132bca649e | ||
| 
						 | 
					87d4491395 | ||
| 
						 | 
					763ec6152b | ||
| 
						 | 
					f26f0389da | ||
| 
						 | 
					6b38985a5f | ||
| 
						 | 
					3bc90e6c06 | ||
| 
						 | 
					d951a9d317 | ||
| 
						 | 
					4731d79a4f | ||
| 
						 | 
					763f29e2b8 | ||
| 
						 | 
					87af923638 | ||
| 
						 | 
					2fdb6fdf37 | ||
| 
						 | 
					295f6f9737 | ||
| 
						 | 
					8f4ba8c21f | ||
| 
						 | 
					329f21093b | ||
| 
						 | 
					605ad788d0 | ||
| 
						 | 
					bcde8b87b1 | ||
| 
						 | 
					cb3b2422a9 | ||
| 
						 | 
					60cc8696e3 | ||
| 
						 | 
					ca4dbabf70 | ||
| 
						 | 
					c1e1e6c3a4 | ||
| 
						 | 
					bcad698164 | ||
| 
						 | 
					d556dae415 | ||
| 
						 | 
					05f287ebbb | ||
| 
						 | 
					90eb0cd844 | ||
| 
						 | 
					a72fc06502 | ||
| 
						 | 
					6b460ce440 | ||
| 
						 | 
					de63669cee | ||
| 
						 | 
					51898ea32b | ||
| 
						 | 
					16f8243fb3 | ||
| 
						 | 
					96c89fc080 | ||
| 
						 | 
					719548213f | ||
| 
						 | 
					836ea55dbd | ||
| 
						 | 
					f197acf8e0 | ||
| 
						 | 
					96aa5b4532 | ||
| 
						 | 
					815bb62ae5 | ||
| 
						 | 
					7cda1d2edd | ||
| 
						 | 
					058e6cbcda | ||
| 
						 | 
					de9e6a7d70 | ||
| 
						 | 
					657a36310b | ||
| 
						 | 
					8656636f01 | ||
| 
						 | 
					c4034d944b | ||
| 
						 | 
					590f16370c | ||
| 
						 | 
					65c1ef7cb5 | ||
| 
						 | 
					723da94e75 | ||
| 
						 | 
					0a0f3dd2b6 | ||
| 
						 | 
					0403749bf1 | ||
| 
						 | 
					f25ff77ee2 | ||
| 
						 | 
					ce5d42ce0f | ||
| 
						 | 
					13d69cb813 | ||
| 
						 | 
					bf60d0576b | ||
| 
						 | 
					678e6f6d74 | ||
| 
						 | 
					88669a4079 | ||
| 
						 | 
					3592fe06bb | ||
| 
						 | 
					e5e9e14a9f | ||
| 
						 | 
					3f890dfb8e | ||
| 
						 | 
					528a815307 | ||
| 
						 | 
					9b57f402da | ||
| 
						 | 
					cf6c930df5 | ||
| 
						 | 
					8f65a644a9 | ||
| 
						 | 
					bba5b21873 | ||
| 
						 | 
					b0149c2712 | ||
| 
						 | 
					7bdccd0ea7 | ||
| 
						 | 
					cce8b73554 | ||
| 
						 | 
					744979a095 | ||
| 
						 | 
					db26df311d | ||
| 
						 | 
					9be9431970 | ||
| 
						 | 
					049bccbdd8 | ||
| 
						 | 
					cf1128b719 | ||
| 
						 | 
					857aaa6ca4 | ||
| 
						 | 
					39915db988 | ||
| 
						 | 
					54385b7606 | ||
| 
						 | 
					87e7233292 | ||
| 
						 | 
					cb92e49363 | ||
| 
						 | 
					a4c714238f | ||
| 
						 | 
					12cd9dd5b2 | ||
| 
						 | 
					60e495bd8c | ||
| 
						 | 
					118e18ac60 | ||
| 
						 | 
					7c3c7c4ff7 | ||
| 
						 | 
					7f7dc04e8d | ||
| 
						 | 
					45daebd989 | ||
| 
						 | 
					ee4da8fcc7 | ||
| 
						 | 
					9f803905cb | ||
| 
						 | 
					1d812f88ce | ||
| 
						 | 
					ada13c19fd | ||
| 
						 | 
					a393ffe126 | ||
| 
						 | 
					9c1e635804 | ||
| 
						 | 
					593c1ca0e2 | ||
| 
						 | 
					8ebd69f4cf | ||
| 
						 | 
					5a83b036b8 | ||
| 
						 | 
					8f1ec4e34a | ||
| 
						 | 
					4e63390e17 | ||
| 
						 | 
					65b9bb0d6b | ||
| 
						 | 
					e1df2a2450 | ||
| 
						 | 
					bd3f89fb57 | ||
| 
						 | 
					f9dc932f62 | ||
| 
						 | 
					4b08aebe7f | ||
| 
						 | 
					1fe27effe5 | ||
| 
						 | 
					453e760709 | ||
| 
						 | 
					0ad9242ab7 | ||
| 
						 | 
					5da736466c | ||
| 
						 | 
					df256b608a | ||
| 
						 | 
					1f5bdef96e | ||
| 
						 | 
					261c3587a5 | ||
| 
						 | 
					a6ba3dfce0 | ||
| 
						 | 
					1bd5628256 | ||
| 
						 | 
					714605ebaa | ||
| 
						 | 
					5975ff9e42 | ||
| 
						 | 
					a27b72e893 | ||
| 
						 | 
					396746acc1 | ||
| 
						 | 
					adc3af0345 | ||
| 
						 | 
					5a82c8123b | ||
| 
						 | 
					8ab1a4fb30 | ||
| 
						 | 
					72701aae21 | ||
| 
						 | 
					419be4df25 | ||
| 
						 | 
					252ec6bcf2 | ||
| 
						 | 
					51f400d8bb | ||
| 
						 | 
					2988f9a651 | ||
| 
						 | 
					d3bd4f49fa | ||
| 
						 | 
					f49627f417 | ||
| 
						 | 
					b587358b11 | ||
| 
						 | 
					e189faabe5 | ||
| 
						 | 
					34b4661268 | ||
| 
						 | 
					9562100580 | ||
| 
						 | 
					e98bf0da72 | ||
| 
						 | 
					cefe3dd4ff | ||
| 
						 | 
					8d71e67a75 | ||
| 
						 | 
					b933485394 | ||
| 
						 | 
					11c79ee537 | ||
| 
						 | 
					3380da638e | ||
| 
						 | 
					87eb5300d2 | ||
| 
						 | 
					e47dc4aa78 | ||
| 
						 | 
					4a6753c867 | ||
| 
						 | 
					226419f794 | ||
| 
						 | 
					6e0a8d8ca1 | ||
| 
						 | 
					7516740bbf | ||
| 
						 | 
					dcfbb766dc | ||
| 
						 | 
					8c84ae9ff6 | ||
| 
						 | 
					683bad19fc | ||
| 
						 | 
					438302fcf5 | ||
| 
						 | 
					06d12fc924 | ||
| 
						 | 
					24162cb162 | ||
| 
						 | 
					e11b42ce50 | ||
| 
						 | 
					4e60f8af13 | ||
| 
						 | 
					3ff5896dc6 | ||
| 
						 | 
					5f4e65bc77 | ||
| 
						 | 
					ad1a4b6479 | ||
| 
						 | 
					73bfc6ca32 | ||
| 
						 | 
					79cc616de2 | ||
| 
						 | 
					5e7746668e | ||
| 
						 | 
					ada9a99804 | ||
| 
						 | 
					0aa2603a23 | ||
| 
						 | 
					0851a8a6a4 | ||
| 
						 | 
					44e66c1318 | ||
| 
						 | 
					b237c73a04 | ||
| 
						 | 
					563c149217 | ||
| 
						 | 
					6017420dde | ||
| 
						 | 
					4948f634ed | ||
| 
						 | 
					a1fce99a05 | ||
| 
						 | 
					37bdfb9faa | ||
| 
						 | 
					9c435e0173 | ||
| 
						 | 
					07572d36c0 | ||
| 
						 | 
					42bc197f67 | ||
| 
						 | 
					ea32c12938 | ||
| 
						 | 
					c24b2b1a8b | ||
| 
						 | 
					5a6e033e82 | ||
| 
						 | 
					e311d7a893 | ||
| 
						 | 
					6def41fab4 | ||
| 
						 | 
					33e7e8da58 | ||
| 
						 | 
					8a49fde016 | ||
| 
						 | 
					8b703ba6a3 | ||
| 
						 | 
					c367731c42 | ||
| 
						 | 
					47c504df5d | ||
| 
						 | 
					1a1009a2a9 | ||
| 
						 | 
					61ee55db6a | ||
| 
						 | 
					35156574b8 | ||
| 
						 | 
					57f2a4c9eb | ||
| 
						 | 
					638c9feeb6 | ||
| 
						 | 
					2f88ba0d3f | ||
| 
						 | 
					09491e4cbb | ||
| 
						 | 
					1554c3a07c | ||
| 
						 | 
					3d0709c779 | ||
| 
						 | 
					ede19c8a61 | ||
| 
						 | 
					3519697d0e | ||
| 
						 | 
					0899eefde7 | ||
| 
						 | 
					d7767afe1b | ||
| 
						 | 
					6831fac76b | ||
| 
						 | 
					6f16d3db83 | ||
| 
						 | 
					b9a1d090ec | ||
| 
						 | 
					bcfd9ec355 | ||
| 
						 | 
					4bf3afac48 | ||
| 
						 | 
					da49becac3 | ||
| 
						 | 
					6324fa3eb9 | ||
| 
						 | 
					7d08770806 | ||
| 
						 | 
					52a82ea1e6 | ||
| 
						 | 
					46ca4d93e7 | ||
| 
						 | 
					4e8d67052f | ||
| 
						 | 
					ad9306d7bb | ||
| 
						 | 
					51c18baedb | ||
| 
						 | 
					f376b42c31 | ||
| 
						 | 
					ad76a2cbe8 | ||
| 
						 | 
					67d2b5568d | ||
| 
						 | 
					0538881447 | ||
| 
						 | 
					653359d815 | ||
| 
						 | 
					7bfb769288 | ||
| 
						 | 
					d5e6e1075d | ||
| 
						 | 
					e0ee2d9514 | ||
| 
						 | 
					1e05e7996b | ||
| 
						 | 
					14c26d01af | ||
| 
						 | 
					e9a98f35ad | ||
| 
						 | 
					38c65e80f3 | ||
| 
						 | 
					f1a47a9f0a | ||
| 
						 | 
					c79fc2e6d9 | ||
| 
						 | 
					b9f22a7526 | ||
| 
						 | 
					bf677df6ca | ||
| 
						 | 
					805fed559c | ||
| 
						 | 
					8913317a44 | ||
| 
						 | 
					74a3a2da78 | ||
| 
						 | 
					854eb845d2 | ||
| 
						 | 
					22ba21f937 | ||
| 
						 | 
					e294221a2d | ||
| 
						 | 
					8a2f60a03a | ||
| 
						 | 
					b7a3f58df4 | ||
| 
						 | 
					a1690ac2d6 | ||
| 
						 | 
					0be4c38a87 | ||
| 
						 | 
					390acd41b2 | ||
| 
						 | 
					c5fa6383d7 | ||
| 
						 | 
					2820316d16 | ||
| 
						 | 
					670d8089bc | ||
| 
						 | 
					1452b74740 | ||
| 
						 | 
					2f3062f4c2 | ||
| 
						 | 
					81fe8b1488 | ||
| 
						 | 
					b8583a1e59 | ||
| 
						 | 
					12a361556b | ||
| 
						 | 
					07a9e3dd46 | ||
| 
						 | 
					1297845e31 | ||
| 
						 | 
					559c53b09c | ||
| 
						 | 
					bc9d8fb13a | ||
| 
						 | 
					bf9f1c95bc | ||
| 
						 | 
					d6825c4986 | ||
| 
						 | 
					3596b48c7a | ||
| 
						 | 
					fc2286117d | ||
| 
						 | 
					e577cd4495 | ||
| 
						 | 
					9bf7212458 | ||
| 
						 | 
					54d31c85e7 | ||
| 
						 | 
					2b485a5e59 | ||
| 
						 | 
					a65723d4da | ||
| 
						 | 
					12b23db286 | ||
| 
						 | 
					f38b518e86 | ||
| 
						 | 
					7e0e063c3f | ||
| 
						 | 
					e8cb5c621a | ||
| 
						 | 
					616f3d4fd7 | ||
| 
						 | 
					e0b8942242 | ||
| 
						 | 
					954e8ee3f8 | ||
| 
						 | 
					4114a2bbe8 | ||
| 
						 | 
					ce67712009 | ||
| 
						 | 
					03e621f4a2 | ||
| 
						 | 
					4d1630bf8b | ||
| 
						 | 
					cbb1a5ef36 | ||
| 
						 | 
					a1fb83bdc4 | ||
| 
						 | 
					53fb16437f | ||
| 
						 | 
					0e977a7e42 | ||
| 
						 | 
					740f1e7fe5 | ||
| 
						 | 
					85a1eb95ee | ||
| 
						 | 
					243c4e6b02 | ||
| 
						 | 
					59f11e9b67 | ||
| 
						 | 
					613d076a60 | ||
| 
						 | 
					51c5c9ba26 | ||
| 
						 | 
					b81bc17560 | ||
| 
						 | 
					f32671ebab | ||
| 
						 | 
					604535f65a | ||
| 
						 | 
					4b2b74bdbd | ||
| 
						 | 
					949f9e466f | ||
| 
						 | 
					d6fe30dfdb | ||
| 
						 | 
					5de99d53d2 | ||
| 
						 | 
					4e588584d7 | ||
| 
						 | 
					9eee00c286 | ||
| 
						 | 
					aba212d700 | ||
| 
						 | 
					f8c3b76367 | ||
| 
						 | 
					6c7e7a6d55 | ||
| 
						 | 
					401a090cae | ||
| 
						 | 
					c98b5d7667 | ||
| 
						 | 
					6bdc655719 | ||
| 
						 | 
					1bf73c29c4 | ||
| 
						 | 
					56f71501cc | ||
| 
						 | 
					e361f52415 | ||
| 
						 | 
					ec99079cdf | ||
| 
						 | 
					8f13e7abb4 | ||
| 
						 | 
					3a5334071d | ||
| 
						 | 
					bc77478b2a | ||
| 
						 | 
					0d2763f68a | ||
| 
						 | 
					9051faf062 | ||
| 
						 | 
					afedc8475d | ||
| 
						 | 
					293844072d | ||
| 
						 | 
					235db9f961 | ||
| 
						 | 
					768760793a | ||
| 
						 | 
					792ba8c0af | ||
| 
						 | 
					a658e88575 | ||
| 
						 | 
					a316f1b40d | ||
| 
						 | 
					1570105ddb | ||
| 
						 | 
					3b7c2b2221 | ||
| 
						 | 
					d2e11dd5d1 | ||
| 
						 | 
					c2d0a247a3 | ||
| 
						 | 
					b43759c6a5 | ||
| 
						 | 
					e8b17b9878 | ||
| 
						 | 
					400a5751f9 | ||
| 
						 | 
					535f81ba8a | ||
| 
						 | 
					7094c7bf39 | ||
| 
						 | 
					fedfed5619 | ||
| 
						 | 
					c2585749ac | ||
| 
						 | 
					a624d91433 | ||
| 
						 | 
					6b9a1530f8 | ||
| 
						 | 
					eb4ffe737e | ||
| 
						 | 
					995646936f | ||
| 
						 | 
					6ea73a8ca2 | ||
| 
						 | 
					373b94b968 | ||
| 
						 | 
					6ccdf79f77 | ||
| 
						 | 
					6bb7df918d | ||
| 
						 | 
					6388b41e6c | ||
| 
						 | 
					e800b2da2d | ||
| 
						 | 
					cc357140e5 | ||
| 
						 | 
					6b2088c94e | ||
| 
						 | 
					3531896892 | ||
| 
						 | 
					96c2c62470 | ||
| 
						 | 
					a4fadcd9be | ||
| 
						 | 
					b5c56fd579 | ||
| 
						 | 
					1a542d3afe | ||
| 
						 | 
					7ea6768852 | ||
| 
						 | 
					56ecf01dea | ||
| 
						 | 
					6a7a486b8c | ||
| 
						 | 
					f1c46d01e9 | ||
| 
						 | 
					8b561a29f5 | ||
| 
						 | 
					fce798dadf | ||
| 
						 | 
					a156d2e63f | ||
| 
						 | 
					ce699d8e3d | ||
| 
						 | 
					00b6694073 | ||
| 
						 | 
					453d533d2c | ||
| 
						 | 
					70df0b0bc8 | ||
| 
						 | 
					c3528e4e40 | ||
| 
						 | 
					67fafa04ac | ||
| 
						 | 
					f494440895 | ||
| 
						 | 
					5e3a0eda73 | ||
| 
						 | 
					ebecfb9f8b | ||
| 
						 | 
					88be947f6c | ||
| 
						 | 
					46f2d72b4c | ||
| 
						 | 
					5f7cfefed7 | ||
| 
						 | 
					c3bc305bb6 | ||
| 
						 | 
					cba5b9e4fb | ||
| 
						 | 
					e5f93d3563 | ||
| 
						 | 
					015f644acf | ||
| 
						 | 
					5d54a08581 | ||
| 
						 | 
					a86ffd105a | ||
| 
						 | 
					d068371e62 | ||
| 
						 | 
					2f25173ac3 | ||
| 
						 | 
					2f7d251000 | ||
| 
						 | 
					1554646a38 | ||
| 
						 | 
					989d08c70a | ||
| 
						 | 
					e5aa90d3a8 | ||
| 
						 | 
					d102750b13 | ||
| 
						 | 
					3dce393dcc | ||
| 
						 | 
					e1bf7ae96f | ||
| 
						 | 
					b54b486ee8 | ||
| 
						 | 
					2b37c41b08 | ||
| 
						 | 
					131352ca03 | ||
| 
						 | 
					e2bf717ea0 | ||
| 
						 | 
					dbfd8bea03 | ||
| 
						 | 
					f06766085a | ||
| 
						 | 
					acb731d823 | ||
| 
						 | 
					54e66ff1c0 | ||
| 
						 | 
					60f8a7c5fb | ||
| 
						 | 
					6936915dd6 | ||
| 
						 | 
					7deb6c0e9e | ||
| 
						 | 
					432154e50a | ||
| 
						 | 
					66f96e339c | ||
| 
						 | 
					17cc0470da | ||
| 
						 | 
					bf7eed9342 | ||
| 
						 | 
					fb7e6101ff | ||
| 
						 | 
					7ce2a87644 | ||
| 
						 | 
					ef436ac4d7 | ||
| 
						 | 
					2a0d4e5a23 | ||
| 
						 | 
					26cabbb3e4 | ||
| 
						 | 
					cd804470b5 | ||
| 
						 | 
					d8a862ec82 | ||
| 
						 | 
					4fa61249a8 | ||
| 
						 | 
					9fa5ab04e5 | ||
| 
						 | 
					f9659989b1 | ||
| 
						 | 
					546253d750 | ||
| 
						 | 
					b29f3e919b | ||
| 
						 | 
					cc0e39db56 | ||
| 
						 | 
					629fc83f21 | ||
| 
						 | 
					69cad09a00 | ||
| 
						 | 
					7b297a0e16 | ||
| 
						 | 
					846936357b | ||
| 
						 | 
					9ef22f4168 | ||
| 
						 | 
					6ee0da41c8 | ||
| 
						 | 
					f0a25bd397 | ||
| 
						 | 
					fa1c848faf | ||
| 
						 | 
					dba346be7a | ||
| 
						 | 
					d71e0a009c | ||
| 
						 | 
					619a6a3f97 | ||
| 
						 | 
					4e1b6f89c7 | ||
| 
						 | 
					983e32c9d9 | ||
| 
						 | 
					185c5d8b51 | ||
| 
						 | 
					8d9c3c428d | ||
| 
						 | 
					242572f57d | ||
| 
						 | 
					d75439e711 | ||
| 
						 | 
					7019b6d663 | ||
| 
						 | 
					4f70568c65 | ||
| 
						 | 
					63c6a8bac8 | ||
| 
						 | 
					f67c7f900c | ||
| 
						 | 
					df634573bf | ||
| 
						 | 
					eb627bc055 | ||
| 
						 | 
					8f81fd7188 | ||
| 
						 | 
					154396f80a | ||
| 
						 | 
					f3c57723df | ||
| 
						 | 
					236bd0eb96 | ||
| 
						 | 
					a57a1fdbd8 | ||
| 
						 | 
					78af510535 | ||
| 
						 | 
					b68e535131 | ||
| 
						 | 
					716328cafb | ||
| 
						 | 
					ddcfd861cc | ||
| 
						 | 
					1825ae1de4 | ||
| 
						 | 
					a72d59d23b | ||
| 
						 | 
					516c8bf7b6 | ||
| 
						 | 
					241c1840aa | ||
| 
						 | 
					fe78ec494f | ||
| 
						 | 
					1021db053d | ||
| 
						 | 
					2d8cf6aabf | ||
| 
						 | 
					03b2c8054b | ||
| 
						 | 
					2107efdd75 | ||
| 
						 | 
					72f97ac163 | ||
| 
						 | 
					2c99a8c6f8 | ||
| 
						 | 
					ffe3209121 | ||
| 
						 | 
					cf341c53fa | ||
| 
						 | 
					74c8f34b79 | ||
| 
						 | 
					e15db9a68c | ||
| 
						 | 
					b419f5a3c3 | ||
| 
						 | 
					93221da5ea | ||
| 
						 | 
					e2d6e63fe6 | ||
| 
						 | 
					d8b8d17e86 | ||
| 
						 | 
					5bf118409a | ||
| 
						 | 
					c333b9bb0a | ||
| 
						 | 
					01911beccc | ||
| 
						 | 
					252a88cb7f | ||
| 
						 | 
					43c172f54d | ||
| 
						 | 
					d0276fd25f | ||
| 
						 | 
					dabd895755 | ||
| 
						 | 
					d630c2aadf | ||
| 
						 | 
					e773fb65a8 | ||
| 
						 | 
					a73ad23b9f | ||
| 
						 | 
					ded7991dd6 | ||
| 
						 | 
					dd670f7c44 | ||
| 
						 | 
					aa4569b55b | ||
| 
						 | 
					bb1df38caa | ||
| 
						 | 
					e186e54434 | ||
| 
						 | 
					98ebb6f8d1 | ||
| 
						 | 
					7830461ac5 | ||
| 
						 | 
					caea146840 | ||
| 
						 | 
					b48de5b908 | ||
| 
						 | 
					e4c97cac2b | ||
| 
						 | 
					efe41da24d | ||
| 
						 | 
					d731e12456 | ||
| 
						 | 
					ea8f5afc3c | ||
| 
						 | 
					ce5b5c6734 | ||
| 
						 | 
					38293b0f09 | ||
| 
						 | 
					a4ad440403 | ||
| 
						 | 
					a888156deb | ||
| 
						 | 
					27f965deb6 | ||
| 
						 | 
					5d577371e7 | ||
| 
						 | 
					da2fff1256 | ||
| 
						 | 
					4543feccca | ||
| 
						 | 
					439d537ca2 | ||
| 
						 | 
					97184dc498 | ||
| 
						 | 
					1a3dc7d386 | ||
| 
						 | 
					e6568667c4 | ||
| 
						 | 
					eee536046b | ||
| 
						 | 
					df20aa9ddb | ||
| 
						 | 
					fb6e65613b | ||
| 
						 | 
					cd7d109114 | ||
| 
						 | 
					a3b84fa674 | ||
| 
						 | 
					f024cb7370 | ||
| 
						 | 
					42888cece6 | ||
| 
						 | 
					bac1108781 | ||
| 
						 | 
					f4fe0881b9 | ||
| 
						 | 
					aa3633e43a | ||
| 
						 | 
					6ce1a49f1c | ||
| 
						 | 
					7521be3c5f | ||
| 
						 | 
					64eafe35d4 | ||
| 
						 | 
					108ba28c43 | ||
| 
						 | 
					192d307d39 | ||
| 
						 | 
					61557cf805 | ||
| 
						 | 
					049b9f9c74 | ||
| 
						 | 
					e400f79673 | ||
| 
						 | 
					4299ea1d4f | ||
| 
						 | 
					231fa815c1 | ||
| 
						 | 
					117418fe60 | ||
| 
						 | 
					788c84dc41 | ||
| 
						 | 
					e4e041df7e | ||
| 
						 | 
					1af8796b2b | ||
| 
						 | 
					cfbe722350 | ||
| 
						 | 
					0143aa5515 | ||
| 
						 | 
					d72e42f7ba | ||
| 
						 | 
					65e78e5915 | ||
| 
						 | 
					91a29c5885 | ||
| 
						 | 
					5e77d65424 | ||
| 
						 | 
					ed14c49a03 | ||
| 
						 | 
					35f4a81768 | ||
| 
						 | 
					a7f983db5f | ||
| 
						 | 
					dd52e10839 | ||
| 
						 | 
					59ea88f1ad | ||
| 
						 | 
					2a9205ebd9 | ||
| 
						 | 
					165e559866 | ||
| 
						 | 
					21d24eeb8d | ||
| 
						 | 
					4dd6ecd54e | ||
| 
						 | 
					9569105575 | ||
| 
						 | 
					850825f70f | ||
| 
						 | 
					bd2fb552b5 | ||
| 
						 | 
					3e26ae5ad6 | ||
| 
						 | 
					cf0119ed4a | ||
| 
						 | 
					039370d410 | ||
| 
						 | 
					af12583122 | ||
| 
						 | 
					fea9886683 | ||
| 
						 | 
					5241e25ae8 | ||
| 
						 | 
					67effe4214 | ||
| 
						 | 
					bd118bb457 | ||
| 
						 | 
					dfedc0fb21 | ||
| 
						 | 
					a21665011f | ||
| 
						 | 
					294d07db7b | ||
| 
						 | 
					5af37b0be3 | ||
| 
						 | 
					3c398bd15e | ||
| 
						 | 
					9651cc0cd7 | ||
| 
						 | 
					0cbbbf811a | ||
| 
						 | 
					44ec9d14a6 | ||
| 
						 | 
					3f1d12ccd8 | ||
| 
						 | 
					2b8309eb04 | ||
| 
						 | 
					adb9f37cca | ||
| 
						 | 
					ea61ac4386 | ||
| 
						 | 
					4912de5893 | ||
| 
						 | 
					a6406ac41b | ||
| 
						 | 
					5691f95833 | ||
| 
						 | 
					3444546159 | ||
| 
						 | 
					9230bd1842 | ||
| 
						 | 
					6bcf4995c9 | ||
| 
						 | 
					5c5c7f28dc | ||
| 
						 | 
					db51e813fb | ||
| 
						 | 
					8a413866a1 | ||
| 
						 | 
					21f52f9dc1 | ||
| 
						 | 
					18b805d43f | ||
| 
						 | 
					b897619558 | ||
| 
						 | 
					b191f39bdf | ||
| 
						 | 
					e7b39303e4 | ||
| 
						 | 
					8949b079e1 | ||
| 
						 | 
					c73e9ec89f | ||
| 
						 | 
					c1aa0b581e | ||
| 
						 | 
					9302ad1468 | ||
| 
						 | 
					b42f86f20f | ||
| 
						 | 
					d109fc5856 | ||
| 
						 | 
					13abe2a5de | ||
| 
						 | 
					c013036f31 | ||
| 
						 | 
					1184229c4a | ||
| 
						 | 
					9d4c2bf1c7 | ||
| 
						 | 
					d19c3b5458 | ||
| 
						 | 
					f8494f27d5 | ||
| 
						 | 
					6a6557e320 | ||
| 
						 | 
					6726a926a4 | ||
| 
						 | 
					7a26143fbc | ||
| 
						 | 
					bf7b41f548 | ||
| 
						 | 
					1fe337d6ed | ||
| 
						 | 
					d4f28e863f | ||
| 
						 | 
					785042ccf3 | ||
| 
						 | 
					0446f03613 | ||
| 
						 | 
					7b09344a8b | ||
| 
						 | 
					70bf033dc0 | ||
| 
						 | 
					1155b6fc3d | ||
| 
						 | 
					4d0cae4a9b | ||
| 
						 | 
					74ce0ba84d | ||
| 
						 | 
					777b582e5b | ||
| 
						 | 
					0ec77f5d85 | ||
| 
						 | 
					df1d7dea61 | ||
| 
						 | 
					0ccd55e33f | ||
| 
						 | 
					b04d59ba2e | ||
| 
						 | 
					42d00ffe38 | ||
| 
						 | 
					af282e092d | ||
| 
						 | 
					53beea6061 | ||
| 
						 | 
					94bd17ecf5 | ||
| 
						 | 
					b95b3dbc78 | ||
| 
						 | 
					22dbe60bb9 | ||
| 
						 | 
					47c167c043 | ||
| 
						 | 
					e2113eda38 | ||
| 
						 | 
					51d414d6ef | ||
| 
						 | 
					71dc9349ad | ||
| 
						 | 
					fac0c90de1 | ||
| 
						 | 
					3c7d97403e | ||
| 
						 | 
					1eba562d07 | ||
| 
						 | 
					9c2a26bed5 | ||
| 
						 | 
					1007680931 | ||
| 
						 | 
					c035029f38 | ||
| 
						 | 
					3d49379bec | ||
| 
						 | 
					b602d423c7 | ||
| 
						 | 
					ac8f99a206 | ||
| 
						 | 
					38ec357bd5 | ||
| 
						 | 
					2be9aece3f | ||
| 
						 | 
					61f579b591 | ||
| 
						 | 
					c2d759f11e | ||
| 
						 | 
					2ebf9124d1 | ||
| 
						 | 
					1cfdc8044c | ||
| 
						 | 
					405fc3dfc2 | ||
| 
						 | 
					7e8ef85dc9 | ||
| 
						 | 
					559b79f920 | ||
| 
						 | 
					10bec1d970 | ||
| 
						 | 
					9665af0e5a | ||
| 
						 | 
					48541629f9 | ||
| 
						 | 
					f3681a533e | ||
| 
						 | 
					488631824d | ||
| 
						 | 
					75eb2c3cd4 | ||
| 
						 | 
					afdf431b77 | ||
| 
						 | 
					1e1b7b7ece | ||
| 
						 | 
					cc6a598c61 | ||
| 
						 | 
					88aa1755ce | ||
| 
						 | 
					a64a54ff04 | ||
| 
						 | 
					0bf1df72cd | ||
| 
						 | 
					dc0164d508 | ||
| 
						 | 
					b5788d4b17 | ||
| 
						 | 
					3600c67485 | ||
| 
						 | 
					6d4a0a1ba3 | ||
| 
						 | 
					ba89f03d8e | ||
| 
						 | 
					4243d5f41a | ||
| 
						 | 
					64f9a2df26 | ||
| 
						 | 
					779e5ecf8f | ||
| 
						 | 
					981e96ea7f | ||
| 
						 | 
					c54e417ff3 | ||
| 
						 | 
					668921543a | ||
| 
						 | 
					63e61e9924 | ||
| 
						 | 
					5ed1dff655 | ||
| 
						 | 
					3588f06767 | ||
| 
						 | 
					fdfe52efe2 | ||
| 
						 | 
					03d086a233 | ||
| 
						 | 
					0379fa9b7d | ||
| 
						 | 
					404a9ef98a | ||
| 
						 | 
					186d32ebee | ||
| 
						 | 
					2b4bc7adf4 | ||
| 
						 | 
					3b9c0bdf91 | ||
| 
						 | 
					bb426ebac4 | ||
| 
						 | 
					9341a84820 | ||
| 
						 | 
					603a7106b3 | ||
| 
						 | 
					9acd2fe458 | ||
| 
						 | 
					f1446736f8 | ||
| 
						 | 
					5b609565e2 | ||
| 
						 | 
					b868894371 | ||
| 
						 | 
					6662cb5f2d | ||
| 
						 | 
					79b4f918fc | ||
| 
						 | 
					8e8525a941 | ||
| 
						 | 
					a90f510b85 | ||
| 
						 | 
					72f67286a4 | ||
| 
						 | 
					8fe2e1f68a | ||
| 
						 | 
					a3a1350dc7 | ||
| 
						 | 
					a4c1f07521 | ||
| 
						 | 
					33fec86ef6 | ||
| 
						 | 
					f8afb15c4c | ||
| 
						 | 
					6556f96442 | ||
| 
						 | 
					416c2c9689 | ||
| 
						 | 
					44ac33845d | ||
| 
						 | 
					46f7e6c131 | ||
| 
						 | 
					8348bd2bb7 | ||
| 
						 | 
					202fe46182 | ||
| 
						 | 
					d2c0c8d638 | ||
| 
						 | 
					b17e01edff | ||
| 
						 | 
					df67f2bb59 | ||
| 
						 | 
					f02cb1a8ea | ||
| 
						 | 
					1c8a72dcac | ||
| 
						 | 
					b9ad701a5c | ||
| 
						 | 
					b96ad4b166 | ||
| 
						 | 
					e60f8bcd06 | ||
| 
						 | 
					4ffa79d4cf | ||
| 
						 | 
					287047fe1a | ||
| 
						 | 
					e9908c84c2 | ||
| 
						 | 
					98d42719e1 | ||
| 
						 | 
					413e160368 | ||
| 
						 | 
					a5091c8c3b | ||
| 
						 | 
					1998405dbb | ||
| 
						 | 
					cdbc5a7b4b | ||
| 
						 | 
					f62bb70b28 | ||
| 
						 | 
					cc310a04b8 | ||
| 
						 | 
					d9ab35f4cc | ||
| 
						 | 
					3fafeaf09a | ||
| 
						 | 
					8625847866 | ||
| 
						 | 
					d3f84980b3 | ||
| 
						 | 
					0716f92f62 | ||
| 
						 | 
					8c7e214376 | ||
| 
						 | 
					b4485f4dc9 | ||
| 
						 | 
					9ae87b7fb7 | ||
| 
						 | 
					d3a27f3c3c | ||
| 
						 | 
					b30eaaddec | ||
| 
						 | 
					c767311062 | ||
| 
						 | 
					9295c91128 | ||
| 
						 | 
					caf18321df | ||
| 
						 | 
					7bae625f46 | ||
| 
						 | 
					b4a21d7aca | ||
| 
						 | 
					3ea796d009 | ||
| 
						 | 
					9fcf9b5fa8 | ||
| 
						 | 
					941cc9c48b | ||
| 
						 | 
					2e90a8d829 | ||
| 
						 | 
					d8dff3dc65 | ||
| 
						 | 
					8b10a9cfc2 | ||
| 
						 | 
					448e478b6d | ||
| 
						 | 
					0be5e04c2e | ||
| 
						 | 
					381a4f9b53 | ||
| 
						 | 
					d9f2f5e988 | ||
| 
						 | 
					63fc1ecca3 | ||
| 
						 | 
					d39f2b8c3e | ||
| 
						 | 
					cb67c79203 | ||
| 
						 | 
					a7b46a02eb | ||
| 
						 | 
					98524708cc | ||
| 
						 | 
					9f17d3fd12 | ||
| 
						 | 
					980e5e13f8 | ||
| 
						 | 
					ea63f48c31 | ||
| 
						 | 
					a1ed303820 | ||
| 
						 | 
					44ec8a7c0b | ||
| 
						 | 
					846d6abaa8 | ||
| 
						 | 
					81badc36f4 | ||
| 
						 | 
					1ff854f05d | ||
| 
						 | 
					efec12d001 | ||
| 
						 | 
					bce6f3f1b7 | ||
| 
						 | 
					3c6683bd98 | ||
| 
						 | 
					f72436aa0a | ||
| 
						 | 
					8af5fb5da5 | ||
| 
						 | 
					1bf95eacb0 | ||
| 
						 | 
					260862fabc | ||
| 
						 | 
					844831751d | ||
| 
						 | 
					92e36558fa | ||
| 
						 | 
					bc2435eb7d | ||
| 
						 | 
					fc8830ae4a | ||
| 
						 | 
					9154228421 | ||
| 
						 | 
					1ebb807624 | ||
| 
						 | 
					430b3b0722 | ||
| 
						 | 
					5349e03ea9 | ||
| 
						 | 
					0b8ef49e7e | ||
| 
						 | 
					c00a382aea | ||
| 
						 | 
					992c673951 | ||
| 
						 | 
					44602d0237 | ||
| 
						 | 
					83e6476be8 | ||
| 
						 | 
					e9384deb5d | ||
| 
						 | 
					bd775a16e2 | ||
| 
						 | 
					aa004503c5 | ||
| 
						 | 
					f8258f671b | ||
| 
						 | 
					6f15b69917 | ||
| 
						 | 
					08df3183dc | ||
| 
						 | 
					19874ebc3a | ||
| 
						 | 
					f94853eb28 | ||
| 
						 | 
					075a28a06d | ||
| 
						 | 
					0d7c1ec130 | ||
| 
						 | 
					5b376b41bf | ||
| 
						 | 
					3ad3a9adfc | ||
| 
						 | 
					04145f49f8 | ||
| 
						 | 
					82223431fa | ||
| 
						 | 
					0f50085bb9 | ||
| 
						 | 
					a8463a8763 | ||
| 
						 | 
					ab7f6abf02 | ||
| 
						 | 
					473576991d | ||
| 
						 | 
					1739d8f15f | ||
| 
						 | 
					6a1e46d7f6 | ||
| 
						 | 
					849da3f322 | ||
| 
						 | 
					c3860849c1 | ||
| 
						 | 
					1496173b2c | ||
| 
						 | 
					3d58127234 | ||
| 
						 | 
					7acc8bcec3 | ||
| 
						 | 
					cc3017be53 | ||
| 
						 | 
					0f87a4a91a | ||
| 
						 | 
					46ab3ac277 | ||
| 
						 | 
					f9a8a9f588 | ||
| 
						 | 
					108e227eec | ||
| 
						 | 
					b30bb7ae0b | ||
| 
						 | 
					24e129a413 | ||
| 
						 | 
					d3acc39d2d | ||
| 
						 | 
					a4682db987 | ||
| 
						 | 
					5af614daf7 | ||
| 
						 | 
					ec4b6752d6 | ||
| 
						 | 
					76a2791b12 | ||
| 
						 | 
					7d024cf72b | ||
| 
						 | 
					9d6d8ecaea | ||
| 
						 | 
					288fe5b274 | ||
| 
						 | 
					40961f21a7 | ||
| 
						 | 
					f0aa515c8b | ||
| 
						 | 
					9c8194402b | ||
| 
						 | 
					cdbf45b5d3 | ||
| 
						 | 
					3a4dcb6913 | ||
| 
						 | 
					7e6c3a2309 | ||
| 
						 | 
					49f4e7b8e1 | ||
| 
						 | 
					ce6fae900f | ||
| 
						 | 
					6bf82e9c65 | ||
| 
						 | 
					d0a65641e2 | ||
| 
						 | 
					112b51756b | ||
| 
						 | 
					f15a599bbd | ||
| 
						 | 
					9738851261 | ||
| 
						 | 
					7057081bdf | ||
| 
						 | 
					e49f0cf3ba | ||
| 
						 | 
					04f4441182 | ||
| 
						 | 
					ca1ae6fd1d | ||
| 
						 | 
					335ccbc149 | ||
| 
						 | 
					cf7391696e | ||
| 
						 | 
					dd8b893ee8 | ||
| 
						 | 
					f045e4f00e | ||
| 
						 | 
					16eff98a06 | ||
| 
						 | 
					0c92a36a53 | ||
| 
						 | 
					6d55005da0 | ||
| 
						 | 
					b16bd6bb23 | ||
| 
						 | 
					67aedd5582 | ||
| 
						 | 
					16bf7925a2 | ||
| 
						 | 
					1896a38ccc | ||
| 
						 | 
					fc034828c7 | ||
| 
						 | 
					1e0295dc65 | ||
| 
						 | 
					84240683f5 | ||
| 
						 | 
					cb4248e56d | ||
| 
						 | 
					c82b802f4e | ||
| 
						 | 
					4ae3a7af61 | ||
| 
						 | 
					b8a9c4c3b7 | ||
| 
						 | 
					2f7790d691 | ||
| 
						 | 
					0d1355d457 | ||
| 
						 | 
					39cae1f0fb | ||
| 
						 | 
					3fbca3ab4c | ||
| 
						 | 
					144b51f00e | ||
| 
						 | 
					17f73b1294 | ||
| 
						 | 
					38fa1d9567 | ||
| 
						 | 
					c43a6ab866 | ||
| 
						 | 
					c98a330bf9 | ||
| 
						 | 
					aae815cf3b | ||
| 
						 | 
					fcf6e2fb25 | ||
| 
						 | 
					1704ad5977 | ||
| 
						 | 
					f3752e200a | ||
| 
						 | 
					c3d27be103 | ||
| 
						 | 
					b9210721e6 | ||
| 
						 | 
					eafb8149b3 | ||
| 
						 | 
					a383aa974a | ||
| 
						 | 
					e99c60728b | ||
| 
						 | 
					18cc4b5c6f | ||
| 
						 | 
					d4a5640446 | ||
| 
						 | 
					4acf0d4d34 | ||
| 
						 | 
					45fb77fbf3 | ||
| 
						 | 
					3d72fb1bbe | ||
| 
						 | 
					a215871da8 | ||
| 
						 | 
					74eada048b | ||
| 
						 | 
					81e5bf4e6e | ||
| 
						 | 
					455cc29bc3 | ||
| 
						 | 
					fa258e3100 | ||
| 
						 | 
					6743de076f | ||
| 
						 | 
					73ab41c572 | ||
| 
						 | 
					343f4cefc8 | ||
| 
						 | 
					a34ca69d52 | ||
| 
						 | 
					7a0e91f076 | ||
| 
						 | 
					14dcbb94a3 | ||
| 
						 | 
					2f18921db9 | ||
| 
						 | 
					3692988b17 | ||
| 
						 | 
					f2bd956b89 | ||
| 
						 | 
					1742c10f7d | ||
| 
						 | 
					eee5674f6d | ||
| 
						 | 
					1da84ca09b | ||
| 
						 | 
					9af44a3c8d | ||
| 
						 | 
					5643c5cdc7 | ||
| 
						 | 
					c5729b861f | ||
| 
						 | 
					bd6aa58322 | ||
| 
						 | 
					3ca770aa63 | ||
| 
						 | 
					413614e14b | ||
| 
						 | 
					a289518a8a | ||
| 
						 | 
					0592d40bc2 | ||
| 
						 | 
					caff0176b1 | ||
| 
						 | 
					0d44d2838f | ||
| 
						 | 
					2ebfae134b | ||
| 
						 | 
					e56bdd019f | ||
| 
						 | 
					7ab9c63903 | ||
| 
						 | 
					5c402ffd66 | ||
| 
						 | 
					1542bad224 | ||
| 
						 | 
					9b15df595e | ||
| 
						 | 
					8e3ed3c933 | ||
| 
						 | 
					721748bed3 | ||
| 
						 | 
					3623e9aefc | ||
| 
						 | 
					67e96d2ce6 | ||
| 
						 | 
					88128e91fe | ||
| 
						 | 
					b85e5b52c2 | ||
| 
						 | 
					db5f3bc309 | ||
| 
						 | 
					319a720d1b | ||
| 
						 | 
					b144d81979 | ||
| 
						 | 
					3be360e433 | ||
| 
						 | 
					8cc114bf2c | ||
| 
						 | 
					f8385d2cb8 | ||
| 
						 | 
					13181a52ee | ||
| 
						 | 
					8c0c84f162 | ||
| 
						 | 
					cd1a4adaf8 | ||
| 
						 | 
					d267d4ab7b | ||
| 
						 | 
					938edf5bd6 | ||
| 
						 | 
					14fbbd92dc | ||
| 
						 | 
					092374d08c | ||
| 
						 | 
					f53f43ad03 | ||
| 
						 | 
					4b6718b354 | ||
| 
						 | 
					942221c764 | ||
| 
						 | 
					945effb048 | ||
| 
						 | 
					b5cfa5109e | ||
| 
						 | 
					4ab30569c2 | ||
| 
						 | 
					4f78afe67e | ||
| 
						 | 
					f0fd47eeb3 | ||
| 
						 | 
					dbd8f361d1 | ||
| 
						 | 
					c1064c5e08 | ||
| 
						 | 
					3cc50d8ac4 | ||
| 
						 | 
					58afa92298 | ||
| 
						 | 
					9dd58b9a22 | ||
| 
						 | 
					7c175f5005 | ||
| 
						 | 
					b4078f3634 | ||
| 
						 | 
					186c065b4c | ||
| 
						 | 
					a2c930a714 | ||
| 
						 | 
					ff66e4b3d5 | ||
| 
						 | 
					f6cb879929 | ||
| 
						 | 
					9a4c599e22 | ||
| 
						 | 
					2a3e616b0e | ||
| 
						 | 
					6978ce3cb4 | ||
| 
						 | 
					520f08bbba | ||
| 
						 | 
					31bf38977e | ||
| 
						 | 
					1ec886e8cb | ||
| 
						 | 
					3ade1fd84a | ||
| 
						 | 
					b709ba7a5b | ||
| 
						 | 
					9482935034 | ||
| 
						 | 
					478af25cec | ||
| 
						 | 
					0ff32784d1 | ||
| 
						 | 
					a9539018e9 | ||
| 
						 | 
					d15aa2bfc3 | ||
| 
						 | 
					dd7a5c45ed | ||
| 
						 | 
					af5c57a713 | ||
| 
						 | 
					c045af1975 | ||
| 
						 | 
					bf9c9a64f1 | ||
| 
						 | 
					132ff59d9c | ||
| 
						 | 
					a3eae323f1 | ||
| 
						 | 
					d74bdbcfd0 | ||
| 
						 | 
					3150785ff1 | ||
| 
						 | 
					1c4bf58fb4 | ||
| 
						 | 
					f0a33a235c | ||
| 
						 | 
					9e6bddf31a | ||
| 
						 | 
					1c285f011b | ||
| 
						 | 
					c963d8905f | ||
| 
						 | 
					271122865f | ||
| 
						 | 
					2ccd5a2043 | ||
| 
						 | 
					b7a27b3f9f | ||
| 
						 | 
					e3a41571f0 | ||
| 
						 | 
					727f7859b7 | ||
| 
						 | 
					b180cbd47d | ||
| 
						 | 
					97eb32bf5c | ||
| 
						 | 
					80a538665e | ||
| 
						 | 
					3f0612b4ad | ||
| 
						 | 
					0f2320bd47 | ||
| 
						 | 
					b98886cdc2 | ||
| 
						 | 
					a299b9dd3a | ||
| 
						 | 
					205fc4f948 | ||
| 
						 | 
					03d1fe434c | ||
| 
						 | 
					b949967529 | ||
| 
						 | 
					59cfdcccdf | ||
| 
						 | 
					0ed0d37693 | ||
| 
						 | 
					afc6e719b4 | ||
| 
						 | 
					ba514506bb | ||
| 
						 | 
					901ff0e4cf | ||
| 
						 | 
					e7610132ce | ||
| 
						 | 
					09b71819c2 | ||
| 
						 | 
					6ef01d83dd | ||
| 
						 | 
					06c6ea04c0 | ||
| 
						 | 
					409a3719cf | ||
| 
						 | 
					3c14d7092a | ||
| 
						 | 
					2ae86fa6e6 | ||
| 
						 | 
					e86f67cad8 | ||
| 
						 | 
					a93e96da7c | ||
| 
						 | 
					e8238ca713 | ||
| 
						 | 
					7859d98a32 | 
@@ -8,6 +8,7 @@ AlignEscapedNewlines: DontAlign
 | 
			
		||||
AllowAllParametersOfDeclarationOnNextLine: "false"
 | 
			
		||||
AllowShortFunctionsOnASingleLine: Inline
 | 
			
		||||
AllowShortIfStatementsOnASingleLine: "false"
 | 
			
		||||
AllowShortLambdasOnASingleLine: All
 | 
			
		||||
AllowShortLoopsOnASingleLine: "false"
 | 
			
		||||
AlwaysBreakAfterReturnType: TopLevelDefinitions
 | 
			
		||||
AlwaysBreakTemplateDeclarations: Yes
 | 
			
		||||
@@ -21,15 +22,16 @@ Cpp11BracedListStyle: "false"
 | 
			
		||||
FixNamespaceComments: "true"
 | 
			
		||||
IncludeBlocks: Preserve
 | 
			
		||||
IndentWidth: "4"
 | 
			
		||||
InsertBraces: "true"
 | 
			
		||||
MaxEmptyLinesToKeep: "2"
 | 
			
		||||
NamespaceIndentation: None
 | 
			
		||||
PointerAlignment: Left
 | 
			
		||||
ReflowComments: "false"
 | 
			
		||||
SortIncludes: "true"
 | 
			
		||||
SpaceAfterCStyleCast: "false"
 | 
			
		||||
SpaceInEmptyBlock: "false"
 | 
			
		||||
SpacesBeforeTrailingComments: "2"
 | 
			
		||||
# SpaceInEmptyBlock: "true"
 | 
			
		||||
SpacesInAngles: "true"
 | 
			
		||||
SpacesInParentheses: "true"
 | 
			
		||||
SpacesInSquareBrackets: "true"
 | 
			
		||||
Standard: Cpp11
 | 
			
		||||
Standard: c++17
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								.gersemirc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								.gersemirc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
#   SPDX-FileCopyrightText: no
 | 
			
		||||
#   SPDX-License-Identifier: CC0-1.0
 | 
			
		||||
#
 | 
			
		||||
# Gersemi configuration
 | 
			
		||||
color: false
 | 
			
		||||
definitions: [ CMakeModules/CalamaresAddTest.cmake ]
 | 
			
		||||
line_length: 120
 | 
			
		||||
quiet: false
 | 
			
		||||
unsafe: false
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										5
									
								
								.git-blame-ignore-revs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								.git-blame-ignore-revs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
#   SPDX-FileCopyrightText: no
 | 
			
		||||
#   SPDX-License-Identifier: CC0-1.0
 | 
			
		||||
#
 | 
			
		||||
18fef8dfe5d926ec0bc979562553adf4db8db2e9
 | 
			
		||||
874a0c1f38b0da4e5bc83083b13a63b1c7eed935
 | 
			
		||||
							
								
								
									
										18
									
								
								.github/workflows/issues.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								.github/workflows/issues.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
			
		||||
name: issues
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  issues:
 | 
			
		||||
    types: [opened, reopened, closed]
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  notify:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: "remove in-progress label"
 | 
			
		||||
        if: github.event.issue.state != 'open'
 | 
			
		||||
        run: |
 | 
			
		||||
          curl -X DELETE \
 | 
			
		||||
            -H 'Accept: application/vnd.github.v3+json' \
 | 
			
		||||
            -H 'Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \
 | 
			
		||||
            "https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.issue.number }}/labels/hacking%3A%20in-progress"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										34
									
								
								.github/workflows/nightly-debian.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								.github/workflows/nightly-debian.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
name: nightly-debian-11
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  schedule:
 | 
			
		||||
    - cron: "12 23 * * *"
 | 
			
		||||
  workflow_dispatch:
 | 
			
		||||
 | 
			
		||||
env:
 | 
			
		||||
  BUILDDIR: /build
 | 
			
		||||
  SRCDIR: ${{ github.workspace }}
 | 
			
		||||
  CMAKE_ARGS: |
 | 
			
		||||
    -DKDE_INSTALL_USE_QT_SYS_PATHS=ON
 | 
			
		||||
    -DCMAKE_BUILD_TYPE=Debug
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  build:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    container:
 | 
			
		||||
      image: docker://debian:11
 | 
			
		||||
      options: --tmpfs /build:rw --user 0:0
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: "prepare git"
 | 
			
		||||
        shell: bash
 | 
			
		||||
        run: |
 | 
			
		||||
            apt-get update
 | 
			
		||||
            apt-get -y install git-core jq curl
 | 
			
		||||
      - name: "prepare source"
 | 
			
		||||
        uses: calamares/actions/generic-checkout@v5
 | 
			
		||||
      - name: "install dependencies"
 | 
			
		||||
        shell: bash
 | 
			
		||||
        run: ./ci/deps-debian11.sh
 | 
			
		||||
      - name: "build"
 | 
			
		||||
        shell: bash
 | 
			
		||||
        run: ./ci/build.sh
 | 
			
		||||
							
								
								
									
										33
									
								
								.github/workflows/nightly-fedora-qt6.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								.github/workflows/nightly-fedora-qt6.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
name: nightly-fedora-qt6
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  schedule:
 | 
			
		||||
    - cron: "52 2 * * *"
 | 
			
		||||
  workflow_dispatch:
 | 
			
		||||
 | 
			
		||||
env:
 | 
			
		||||
  BUILDDIR: /build
 | 
			
		||||
  SRCDIR: ${{ github.workspace }}
 | 
			
		||||
  CMAKE_ARGS: |
 | 
			
		||||
    -DKDE_INSTALL_USE_QT_SYS_PATHS=ON
 | 
			
		||||
    -DCMAKE_BUILD_TYPE=Debug
 | 
			
		||||
    -DWITH_QT6=ON
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  build:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    container:
 | 
			
		||||
      image: docker://registry.fedoraproject.org/fedora:40
 | 
			
		||||
      options: --tmpfs /build:rw --user 0:0
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: "prepare git"
 | 
			
		||||
        shell: bash
 | 
			
		||||
        run: yum install -y git-core jq curl
 | 
			
		||||
      - name: "prepare source"
 | 
			
		||||
        uses: calamares/actions/generic-checkout@v5
 | 
			
		||||
      - name: "install dependencies"
 | 
			
		||||
        shell: bash
 | 
			
		||||
        run: ./ci/deps-fedora-qt6.sh
 | 
			
		||||
      - name: "build"
 | 
			
		||||
        shell: bash
 | 
			
		||||
        run: ./ci/build.sh
 | 
			
		||||
							
								
								
									
										29
									
								
								.github/workflows/nightly-neon-unstable.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								.github/workflows/nightly-neon-unstable.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
name: nightly-neon-unstable
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  schedule:
 | 
			
		||||
    - cron: "59 23 * * *"
 | 
			
		||||
  workflow_dispatch:
 | 
			
		||||
 | 
			
		||||
env:
 | 
			
		||||
  BUILDDIR: /build
 | 
			
		||||
  SRCDIR: ${{ github.workspace }}
 | 
			
		||||
  CMAKE_ARGS: |
 | 
			
		||||
    -DKDE_INSTALL_USE_QT_SYS_PATHS=ON
 | 
			
		||||
    -DCMAKE_BUILD_TYPE=Debug
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  build:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    container:
 | 
			
		||||
      image: docker://kdeneon/plasma:unstable
 | 
			
		||||
      options: --tmpfs /build:rw --user 0:0
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: "prepare source"
 | 
			
		||||
        uses: calamares/actions/generic-checkout@v5
 | 
			
		||||
      - name: "install dependencies"
 | 
			
		||||
        shell: bash
 | 
			
		||||
        run: ./ci/deps-neon.sh
 | 
			
		||||
      - name: "build"
 | 
			
		||||
        shell: bash
 | 
			
		||||
        run: ./ci/build.sh
 | 
			
		||||
							
								
								
									
										41
									
								
								.github/workflows/nightly-neon.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								.github/workflows/nightly-neon.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
name: nightly-neon
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  schedule:
 | 
			
		||||
    - cron: "52 23 * * *"
 | 
			
		||||
  workflow_dispatch:
 | 
			
		||||
 | 
			
		||||
env:
 | 
			
		||||
  BUILDDIR: /build
 | 
			
		||||
  SRCDIR: ${{ github.workspace }}
 | 
			
		||||
  CMAKE_ARGS: |
 | 
			
		||||
    -DKDE_INSTALL_USE_QT_SYS_PATHS=ON
 | 
			
		||||
    -DCMAKE_BUILD_TYPE=Debug
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  build:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    container:
 | 
			
		||||
      image: docker://kdeneon/plasma:user
 | 
			
		||||
      options: --tmpfs /build:rw --user 0:0
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: "prepare source"
 | 
			
		||||
        uses: calamares/actions/generic-checkout@v5
 | 
			
		||||
      - name: "install dependencies"
 | 
			
		||||
        shell: bash
 | 
			
		||||
        run: ./ci/deps-neon.sh
 | 
			
		||||
      - name: "build"
 | 
			
		||||
        shell: bash
 | 
			
		||||
        run: ./ci/build.sh
 | 
			
		||||
      - name: "Calamares: archive"
 | 
			
		||||
        working-directory: ${{ env.BUILDDIR }}
 | 
			
		||||
        run: |
 | 
			
		||||
          DESTDIR=${{ env.BUILDDIR }}/stage ninja install
 | 
			
		||||
          tar czf calamares.tar.gz stage
 | 
			
		||||
      - name: "Calamares: upload"
 | 
			
		||||
        uses: actions/upload-artifact@v3
 | 
			
		||||
        with:
 | 
			
		||||
          name: calamares-tarball
 | 
			
		||||
          path: ${{ env.BUILDDIR }}/calamares.tar.gz
 | 
			
		||||
          if-no-files-found: error
 | 
			
		||||
          retention-days: 7
 | 
			
		||||
							
								
								
									
										33
									
								
								.github/workflows/nightly-opensuse-qt6.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								.github/workflows/nightly-opensuse-qt6.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
name: nightly-opensuse-qt6
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  schedule:
 | 
			
		||||
    - cron: "32 2 * * *"
 | 
			
		||||
  workflow_dispatch:
 | 
			
		||||
 | 
			
		||||
env:
 | 
			
		||||
  BUILDDIR: /build
 | 
			
		||||
  SRCDIR: ${{ github.workspace }}
 | 
			
		||||
  CMAKE_ARGS: |
 | 
			
		||||
    -DKDE_INSTALL_USE_QT_SYS_PATHS=ON
 | 
			
		||||
    -DCMAKE_BUILD_TYPE=Debug
 | 
			
		||||
    -DWITH_QT6=ON
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  build:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    container:
 | 
			
		||||
      image: docker://opensuse/tumbleweed
 | 
			
		||||
      options: --tmpfs /build:rw --user 0:0
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: "prepare git"
 | 
			
		||||
        shell: bash
 | 
			
		||||
        run: zypper --non-interactive in git-core jq curl
 | 
			
		||||
      - name: "prepare source"
 | 
			
		||||
        uses: calamares/actions/generic-checkout@v5
 | 
			
		||||
      - name: "install dependencies"
 | 
			
		||||
        shell: bash
 | 
			
		||||
        run: ./ci/deps-opensuse-qt6.sh
 | 
			
		||||
      - name: "build"
 | 
			
		||||
        shell: bash
 | 
			
		||||
        run: ./ci/build.sh
 | 
			
		||||
							
								
								
									
										34
									
								
								.github/workflows/nightly-opensuse.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								.github/workflows/nightly-opensuse.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
name: nightly-opensuse
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  schedule:
 | 
			
		||||
    - cron: "32 23 * * *"
 | 
			
		||||
  workflow_dispatch:
 | 
			
		||||
 | 
			
		||||
env:
 | 
			
		||||
  BUILDDIR: /build
 | 
			
		||||
  SRCDIR: ${{ github.workspace }}
 | 
			
		||||
  CMAKE_ARGS: |
 | 
			
		||||
    -DKDE_INSTALL_USE_QT_SYS_PATHS=ON
 | 
			
		||||
    -DCMAKE_BUILD_TYPE=Debug
 | 
			
		||||
    -DBUILD_SCHEMA_TESTING=ON
 | 
			
		||||
    -DBUILD_TESTING=ON
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  build:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    container:
 | 
			
		||||
      image: docker://opensuse/tumbleweed
 | 
			
		||||
      options: --tmpfs /build:rw --user 0:0
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: "prepare git"
 | 
			
		||||
        shell: bash
 | 
			
		||||
        run: zypper --non-interactive in git-core jq curl
 | 
			
		||||
      - name: "prepare source"
 | 
			
		||||
        uses: calamares/actions/generic-checkout@v5
 | 
			
		||||
      - name: "install dependencies"
 | 
			
		||||
        shell: bash
 | 
			
		||||
        run: ./ci/deps-opensuse.sh
 | 
			
		||||
      - name: "build"
 | 
			
		||||
        shell: bash
 | 
			
		||||
        run: ./ci/build.sh
 | 
			
		||||
							
								
								
									
										38
									
								
								.github/workflows/push.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								.github/workflows/push.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
name: ci-push
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
    branches:
 | 
			
		||||
      - calamares
 | 
			
		||||
  pull_request:
 | 
			
		||||
    types:
 | 
			
		||||
      - opened
 | 
			
		||||
      - reopened
 | 
			
		||||
      - synchronize
 | 
			
		||||
  workflow_dispatch:
 | 
			
		||||
 | 
			
		||||
env:
 | 
			
		||||
  BUILDDIR: /build
 | 
			
		||||
  SRCDIR: ${{ github.workspace }}
 | 
			
		||||
  CMAKE_ARGS: |
 | 
			
		||||
    -DWEBVIEW_FORCE_WEBKIT=1
 | 
			
		||||
    -DKDE_INSTALL_USE_QT_SYS_PATHS=ON
 | 
			
		||||
    -DWITH_PYTHONQT=OFF
 | 
			
		||||
    -DCMAKE_BUILD_TYPE=Debug
 | 
			
		||||
  GIT_HASH: ${{ github.event.head_commit.id }}
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  build:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    container:
 | 
			
		||||
      image: docker://kdeneon/plasma:user
 | 
			
		||||
      options: --tmpfs /build:rw --user 0:0
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: "prepare source"
 | 
			
		||||
        uses: calamares/actions/generic-checkout@v5
 | 
			
		||||
      - name: "install dependencies"
 | 
			
		||||
        shell: bash
 | 
			
		||||
        run: ./ci/deps-neon.sh
 | 
			
		||||
      - name: "build"
 | 
			
		||||
        shell: bash
 | 
			
		||||
        run: ./ci/build.sh
 | 
			
		||||
							
								
								
									
										23
									
								
								.reuse/dep5
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								.reuse/dep5
									
									
									
									
									
								
							@@ -15,6 +15,10 @@ Files: man/calamares.8
 | 
			
		||||
License: GPL-3.0-or-later
 | 
			
		||||
Copyright: 2017 Jonathan Carter <jcarter@linux.com>
 | 
			
		||||
 | 
			
		||||
Files: 3rdparty/kdsingleapplication/*
 | 
			
		||||
License: MIT
 | 
			
		||||
Copyright: Copyright (C) 2019-2021 Klarälvdalens Datakonsult AB, a KDAB Group company, info@ kdab.com
 | 
			
		||||
 | 
			
		||||
### BUILD ARTIFACTS / NOT SOURCE
 | 
			
		||||
#
 | 
			
		||||
# QRC Files are basically build artifacts
 | 
			
		||||
@@ -29,6 +33,11 @@ Files: .github/ISSUE_TEMPLATE/*
 | 
			
		||||
License: CC0-1.0
 | 
			
		||||
Copyright: no
 | 
			
		||||
 | 
			
		||||
# GitHub actions are not part of the source
 | 
			
		||||
Files: .github/workflows/*.yml
 | 
			
		||||
License: CC0-1.0
 | 
			
		||||
Copyright: no
 | 
			
		||||
 | 
			
		||||
# Packaging information
 | 
			
		||||
#
 | 
			
		||||
Files: data/FreeBSD/distinfo data/FreeBSD/pkg-descr data/FreeBSD/pkg-plist
 | 
			
		||||
@@ -45,6 +54,13 @@ Files: data/example-root/usr/share/zoneinfo/Zulu data/example-root/usr/share/zon
 | 
			
		||||
License: CC0-1.0
 | 
			
		||||
Copyright: no
 | 
			
		||||
 | 
			
		||||
# Test data
 | 
			
		||||
#
 | 
			
		||||
# These first files are mere lists of locale identifiers
 | 
			
		||||
Files: src/modules/locale/tests/locale-data-neon src/modules/locale/tests/locale-data-freebsd
 | 
			
		||||
License: CC0-1.0
 | 
			
		||||
Copyright: no
 | 
			
		||||
 | 
			
		||||
### TRANSLATIONS
 | 
			
		||||
#
 | 
			
		||||
# .desktop files and template change only with translation
 | 
			
		||||
@@ -76,10 +92,3 @@ Files: lang/python/*/LC_MESSAGES/python.po
 | 
			
		||||
License: GPL-3.0-or-later
 | 
			
		||||
Copyright: 2020 Calamares authors and translators
 | 
			
		||||
 | 
			
		||||
Files: src/modules/dummypythonqt/lang/dummypythonqt.pot
 | 
			
		||||
License: GPL-3.0-or-later
 | 
			
		||||
Copyright: 2020 Calamares authors and translators
 | 
			
		||||
 | 
			
		||||
Files: src/modules/dummypythonqt/lang/*/LC_MESSAGES/dummypythonqt.po
 | 
			
		||||
License: GPL-3.0-or-later
 | 
			
		||||
Copyright: 2020 Calamares authors and translators
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										23
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								.travis.yml
									
									
									
									
									
								
							@@ -1,23 +0,0 @@
 | 
			
		||||
#   SPDX-FileCopyrightText: no
 | 
			
		||||
#   SPDX-License-Identifier: CC0-1.0
 | 
			
		||||
#
 | 
			
		||||
language: cpp
 | 
			
		||||
 | 
			
		||||
python:
 | 
			
		||||
  - 3.5
 | 
			
		||||
 | 
			
		||||
sudo: required
 | 
			
		||||
 | 
			
		||||
services:
 | 
			
		||||
  - docker
 | 
			
		||||
 | 
			
		||||
notifications:
 | 
			
		||||
  irc:
 | 
			
		||||
    - "chat.freenode.net#calamares"
 | 
			
		||||
 | 
			
		||||
install:
 | 
			
		||||
  - docker build -t calamares .
 | 
			
		||||
 | 
			
		||||
script:
 | 
			
		||||
  - docker run -v $PWD:/src --tmpfs /build:rw,size=112M -e SRCDIR=/src -e BUILDDIR=/build calamares "/src/ci/travis.sh"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										14
									
								
								.tx/config
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								.tx/config
									
									
									
									
									
								
							@@ -2,23 +2,23 @@
 | 
			
		||||
#   SPDX-License-Identifier: CC0-1.0
 | 
			
		||||
 | 
			
		||||
[main]
 | 
			
		||||
host = https://www.transifex.com
 | 
			
		||||
host = https://app.transifex.com
 | 
			
		||||
 | 
			
		||||
[calamares.calamares]
 | 
			
		||||
[o:calamares:p:calamares:r:calamares]
 | 
			
		||||
file_filter = lang/calamares_<lang>.ts
 | 
			
		||||
source_file = lang/calamares_en.ts
 | 
			
		||||
source_lang = en
 | 
			
		||||
type = QT
 | 
			
		||||
type        = QT
 | 
			
		||||
 | 
			
		||||
[calamares.fdo]
 | 
			
		||||
[o:calamares:p:calamares:r:fdo]
 | 
			
		||||
file_filter = lang/desktop_<lang>.desktop
 | 
			
		||||
source_file = calamares.desktop
 | 
			
		||||
source_lang = en
 | 
			
		||||
type = DESKTOP
 | 
			
		||||
type        = DESKTOP
 | 
			
		||||
 | 
			
		||||
[calamares.python]
 | 
			
		||||
[o:calamares:p:calamares:r:python]
 | 
			
		||||
file_filter = lang/python/<lang>/LC_MESSAGES/python.po
 | 
			
		||||
source_file = lang/python.pot
 | 
			
		||||
source_lang = en
 | 
			
		||||
type = PO
 | 
			
		||||
type        = PO
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										26
									
								
								3rdparty/kdsingleapplication/CMakeLists.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								3rdparty/kdsingleapplication/CMakeLists.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
set(KDSINGLEAPPLICATION_STATIC ON)
 | 
			
		||||
 | 
			
		||||
set(KDSINGLEAPPLICATION_SRCS kdsingleapplication.cpp kdsingleapplication_localsocket.cpp)
 | 
			
		||||
 | 
			
		||||
set(KDSINGLEAPPLICATION_INSTALLABLE_INCLUDES kdsingleapplication.h kdsingleapplication_lib.h)
 | 
			
		||||
 | 
			
		||||
set(KDSINGLEAPPLICATION_NON_INSTALLABLE_INCLUDES kdsingleapplication_localsocket_p.h)
 | 
			
		||||
 | 
			
		||||
if(KDSINGLEAPPLICATION_STATIC)
 | 
			
		||||
    add_library(kdsingleapplication STATIC ${KDSINGLEAPPLICATION_INSTALLABLE_INCLUDES} ${KDSINGLEAPPLICATION_SRCS})
 | 
			
		||||
    target_compile_definitions(kdsingleapplication PUBLIC KDSINGLEAPPLICATION_STATIC_BUILD)
 | 
			
		||||
else()
 | 
			
		||||
    add_library(kdsingleapplication SHARED ${KDSINGLEAPPLICATION_INSTALLABLE_INCLUDES} ${KDSINGLEAPPLICATION_SRCS})
 | 
			
		||||
    target_compile_definitions(kdsingleapplication PRIVATE KDSINGLEAPPLICATION_SHARED_BUILD)
 | 
			
		||||
endif()
 | 
			
		||||
set_target_properties( kdsingleapplication PROPERTIES AUTOMOC TRUE )
 | 
			
		||||
 | 
			
		||||
set(KDSINGLEAPPLICATION_INCLUDEDIR ${CMAKE_INSTALL_INCLUDEDIR}/kdsingleapplication)
 | 
			
		||||
 | 
			
		||||
target_include_directories(
 | 
			
		||||
    kdsingleapplication
 | 
			
		||||
    PUBLIC $<INSTALL_INTERFACE:${KDSINGLEAPPLICATION_INCLUDEDIR}> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
 | 
			
		||||
    PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
target_link_libraries(kdsingleapplication ${qtname}::Core ${qtname}::Network)
 | 
			
		||||
							
								
								
									
										22
									
								
								3rdparty/kdsingleapplication/LICENSE.MIT.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								3rdparty/kdsingleapplication/LICENSE.MIT.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
MIT License
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2019-2021 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
in the Software without restriction, including without limitation the rights
 | 
			
		||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
furnished to do so, subject to the following conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
SOFTWARE.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										123
									
								
								3rdparty/kdsingleapplication/kdsingleapplication.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								3rdparty/kdsingleapplication/kdsingleapplication.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,123 @@
 | 
			
		||||
/*
 | 
			
		||||
    MIT License
 | 
			
		||||
 | 
			
		||||
    Copyright (C) 2019-2021 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
 | 
			
		||||
 | 
			
		||||
    Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
    of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
    in the Software without restriction, including without limitation the rights
 | 
			
		||||
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
    copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
    furnished to do so, subject to the following conditions:
 | 
			
		||||
 | 
			
		||||
    The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
    copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
    SOFTWARE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "kdsingleapplication.h"
 | 
			
		||||
 | 
			
		||||
#include <QtCore/QCoreApplication>
 | 
			
		||||
#include <QtCore/QFileInfo>
 | 
			
		||||
 | 
			
		||||
// TODO: make this pluggable.
 | 
			
		||||
#include "kdsingleapplication_localsocket_p.h"
 | 
			
		||||
 | 
			
		||||
// Avoiding dragging in Qt private APIs for now, so this does not inherit
 | 
			
		||||
// from QObjectPrivate.
 | 
			
		||||
class KDSingleApplicationPrivate
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    explicit KDSingleApplicationPrivate(const QString &name, KDSingleApplication *q);
 | 
			
		||||
 | 
			
		||||
    void initialize();
 | 
			
		||||
 | 
			
		||||
    QString name() const
 | 
			
		||||
    {
 | 
			
		||||
        return m_name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool isPrimaryInstance() const
 | 
			
		||||
    {
 | 
			
		||||
        return m_impl.isPrimaryInstance();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool sendMessage(const QByteArray &message, int timeout)
 | 
			
		||||
    {
 | 
			
		||||
        return m_impl.sendMessage(message, timeout);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    Q_DECLARE_PUBLIC(KDSingleApplication)
 | 
			
		||||
 | 
			
		||||
    KDSingleApplication *q_ptr;
 | 
			
		||||
    QString m_name;
 | 
			
		||||
 | 
			
		||||
    KDSingleApplicationLocalSocket m_impl;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
KDSingleApplicationPrivate::KDSingleApplicationPrivate(const QString &name, KDSingleApplication *q)
 | 
			
		||||
    : q_ptr(q)
 | 
			
		||||
    , m_name(name)
 | 
			
		||||
    , m_impl(name)
 | 
			
		||||
{
 | 
			
		||||
    if (Q_UNLIKELY(name.isEmpty()))
 | 
			
		||||
        qFatal("KDSingleApplication requires a non-empty application name");
 | 
			
		||||
 | 
			
		||||
    if (isPrimaryInstance()) {
 | 
			
		||||
        QObject::connect(&m_impl, &KDSingleApplicationLocalSocket::messageReceived,
 | 
			
		||||
                         q, &KDSingleApplication::messageReceived);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static QString extractExecutableName(const QString &applicationFilePath)
 | 
			
		||||
{
 | 
			
		||||
    return QFileInfo(applicationFilePath).fileName();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
KDSingleApplication::KDSingleApplication(QObject *parent)
 | 
			
		||||
    : KDSingleApplication(extractExecutableName(QCoreApplication::applicationFilePath()), parent)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
KDSingleApplication::KDSingleApplication(const QString &name, QObject *parent)
 | 
			
		||||
    : QObject(parent)
 | 
			
		||||
    , d_ptr(new KDSingleApplicationPrivate(name, this))
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString KDSingleApplication::name() const
 | 
			
		||||
{
 | 
			
		||||
    Q_D(const KDSingleApplication);
 | 
			
		||||
    return d->name();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool KDSingleApplication::isPrimaryInstance() const
 | 
			
		||||
{
 | 
			
		||||
    Q_D(const KDSingleApplication);
 | 
			
		||||
    return d->isPrimaryInstance();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool KDSingleApplication::sendMessage(const QByteArray &message)
 | 
			
		||||
{
 | 
			
		||||
    return sendMessageWithTimeout(message, 5000);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool KDSingleApplication::sendMessageWithTimeout(const QByteArray &message, int timeout)
 | 
			
		||||
{
 | 
			
		||||
    Q_ASSERT(!isPrimaryInstance());
 | 
			
		||||
 | 
			
		||||
    Q_D(KDSingleApplication);
 | 
			
		||||
    return d->sendMessage(message, timeout);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
KDSingleApplication::~KDSingleApplication() = default;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										62
									
								
								3rdparty/kdsingleapplication/kdsingleapplication.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								3rdparty/kdsingleapplication/kdsingleapplication.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
/*
 | 
			
		||||
    MIT License
 | 
			
		||||
 | 
			
		||||
    Copyright (C) 2019-2021 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
 | 
			
		||||
 | 
			
		||||
    Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
    of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
    in the Software without restriction, including without limitation the rights
 | 
			
		||||
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
    copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
    furnished to do so, subject to the following conditions:
 | 
			
		||||
 | 
			
		||||
    The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
    copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
    SOFTWARE.
 | 
			
		||||
*/
 | 
			
		||||
#ifndef KDSINGLEAPPLICATION_H
 | 
			
		||||
#define KDSINGLEAPPLICATION_H
 | 
			
		||||
 | 
			
		||||
#include <QtCore/QObject>
 | 
			
		||||
 | 
			
		||||
#include <memory>
 | 
			
		||||
 | 
			
		||||
#include "kdsingleapplication_lib.h"
 | 
			
		||||
 | 
			
		||||
class KDSingleApplicationPrivate;
 | 
			
		||||
 | 
			
		||||
class KDSINGLEAPPLICATION_EXPORT KDSingleApplication : public QObject
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
    Q_PROPERTY(QString name READ name CONSTANT)
 | 
			
		||||
    Q_PROPERTY(bool isPrimaryInstance READ isPrimaryInstance CONSTANT)
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    explicit KDSingleApplication(QObject *parent = nullptr);
 | 
			
		||||
    explicit KDSingleApplication(const QString &name, QObject *parent = nullptr);
 | 
			
		||||
    ~KDSingleApplication();
 | 
			
		||||
 | 
			
		||||
    QString name() const;
 | 
			
		||||
    bool isPrimaryInstance() const;
 | 
			
		||||
 | 
			
		||||
public Q_SLOTS:
 | 
			
		||||
    // avoid default arguments and overloads, as they don't mix with connections
 | 
			
		||||
    bool sendMessage(const QByteArray &message);
 | 
			
		||||
    bool sendMessageWithTimeout(const QByteArray &message, int timeout);
 | 
			
		||||
 | 
			
		||||
Q_SIGNALS:
 | 
			
		||||
    void messageReceived(const QByteArray &message);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    Q_DECLARE_PRIVATE(KDSingleApplication)
 | 
			
		||||
    std::unique_ptr<KDSingleApplicationPrivate> d_ptr;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // KDSINGLEAPPLICATION_H
 | 
			
		||||
							
								
								
									
										37
									
								
								3rdparty/kdsingleapplication/kdsingleapplication_lib.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								3rdparty/kdsingleapplication/kdsingleapplication_lib.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
/*
 | 
			
		||||
    MIT License
 | 
			
		||||
 | 
			
		||||
    Copyright (C) 2019-2021 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
 | 
			
		||||
 | 
			
		||||
    Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
    of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
    in the Software without restriction, including without limitation the rights
 | 
			
		||||
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
    copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
    furnished to do so, subject to the following conditions:
 | 
			
		||||
 | 
			
		||||
    The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
    copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
    SOFTWARE.
 | 
			
		||||
*/
 | 
			
		||||
#ifndef KDSINGLEAPPLICATION_LIB_H
 | 
			
		||||
#define KDSINGLEAPPLICATION_LIB_H
 | 
			
		||||
 | 
			
		||||
#include <QtCore/QtGlobal>
 | 
			
		||||
 | 
			
		||||
#if defined(KDSINGLEAPPLICATION_STATIC_BUILD)
 | 
			
		||||
#define KDSINGLEAPPLICATION_EXPORT
 | 
			
		||||
#elif defined(KDSINGLEAPPLICATION_SHARED_BUILD)
 | 
			
		||||
#define KDSINGLEAPPLICATION_EXPORT Q_DECL_EXPORT
 | 
			
		||||
#else
 | 
			
		||||
#define KDSINGLEAPPLICATION_EXPORT Q_DECL_IMPORT
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // KDSINGLEAPPLICATION_LIB_H
 | 
			
		||||
							
								
								
									
										304
									
								
								3rdparty/kdsingleapplication/kdsingleapplication_localsocket.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										304
									
								
								3rdparty/kdsingleapplication/kdsingleapplication_localsocket.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,304 @@
 | 
			
		||||
/*
 | 
			
		||||
    MIT License
 | 
			
		||||
 | 
			
		||||
    Copyright (C) 2019-2021 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
 | 
			
		||||
 | 
			
		||||
    Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
    of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
    in the Software without restriction, including without limitation the rights
 | 
			
		||||
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
    copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
    furnished to do so, subject to the following conditions:
 | 
			
		||||
 | 
			
		||||
    The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
    copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
    SOFTWARE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "kdsingleapplication_localsocket_p.h"
 | 
			
		||||
 | 
			
		||||
#include <QtCore/QDir>
 | 
			
		||||
#include <QtCore/QDeadlineTimer>
 | 
			
		||||
#include <QtCore/QTimer>
 | 
			
		||||
#include <QtCore/QLockFile>
 | 
			
		||||
#include <QtCore/QDataStream>
 | 
			
		||||
 | 
			
		||||
#include <QtCore/QtDebug>
 | 
			
		||||
#include <QtCore/QLoggingCategory>
 | 
			
		||||
 | 
			
		||||
#include <QtNetwork/QLocalServer>
 | 
			
		||||
#include <QtNetwork/QLocalSocket>
 | 
			
		||||
 | 
			
		||||
#include <chrono>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
 | 
			
		||||
#if defined(Q_OS_UNIX)
 | 
			
		||||
// for ::getuid()
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(Q_OS_WIN)
 | 
			
		||||
#include <qt_windows.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static const auto LOCALSOCKET_CONNECTION_TIMEOUT = std::chrono::seconds(5);
 | 
			
		||||
static const char LOCALSOCKET_PROTOCOL_VERSION = 2;
 | 
			
		||||
 | 
			
		||||
Q_LOGGING_CATEGORY(kdsaLocalSocket, "kdsingleapplication.localsocket", QtWarningMsg);
 | 
			
		||||
 | 
			
		||||
KDSingleApplicationLocalSocket::KDSingleApplicationLocalSocket(const QString &name, QObject *parent)
 | 
			
		||||
    : QObject(parent)
 | 
			
		||||
{
 | 
			
		||||
#if defined(Q_OS_UNIX)
 | 
			
		||||
    m_socketName = QStringLiteral("kdsingleapp-%1-%2-%3")
 | 
			
		||||
            .arg(::getuid())
 | 
			
		||||
            .arg(qEnvironmentVariable("XDG_SESSION_ID"), name);
 | 
			
		||||
#elif defined(Q_OS_WIN)
 | 
			
		||||
    // I'm not sure of a "global session identifier" on Windows; are
 | 
			
		||||
    // multiple logins from the same user a possibility? For now, following this:
 | 
			
		||||
    // https://docs.microsoft.com/en-us/windows/desktop/devnotes/getting-the-session-id-of-the-current-process
 | 
			
		||||
 | 
			
		||||
    DWORD sessionId;
 | 
			
		||||
    BOOL haveSessionId = ProcessIdToSessionId(GetCurrentProcessId(), &sessionId);
 | 
			
		||||
 | 
			
		||||
    m_socketName = QString::fromUtf8("kdsingleapp-%1-%2")
 | 
			
		||||
            .arg(haveSessionId ? sessionId : 0)
 | 
			
		||||
            .arg(name);
 | 
			
		||||
#else
 | 
			
		||||
#error "KDSingleApplication has not been ported to this platform"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    const QString lockFilePath =
 | 
			
		||||
            QDir::tempPath() + QLatin1Char('/') + m_socketName + QLatin1String(".lock");
 | 
			
		||||
 | 
			
		||||
    qCDebug(kdsaLocalSocket) << "Socket name is" << m_socketName;
 | 
			
		||||
    qCDebug(kdsaLocalSocket) << "Lock file path is" << lockFilePath;
 | 
			
		||||
 | 
			
		||||
    std::unique_ptr<QLockFile> lockFile(new QLockFile(lockFilePath));
 | 
			
		||||
    lockFile->setStaleLockTime(0);
 | 
			
		||||
 | 
			
		||||
    if (!lockFile->tryLock()) {
 | 
			
		||||
        // someone else has the lock => we're secondary
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::unique_ptr<QLocalServer> server = std::make_unique<QLocalServer>();
 | 
			
		||||
    if (!server->listen(m_socketName)) {
 | 
			
		||||
        // maybe the primary crashed, leaving a stale socket; delete it and try again
 | 
			
		||||
        QLocalServer::removeServer(m_socketName);
 | 
			
		||||
        if (!server->listen(m_socketName)) {
 | 
			
		||||
            // TODO: better error handling.
 | 
			
		||||
            qWarning("KDSingleApplication: unable to make the primary instance listen on %ls: %ls",
 | 
			
		||||
                     qUtf16Printable(m_socketName),
 | 
			
		||||
                     qUtf16Printable(server->errorString()));
 | 
			
		||||
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    connect(server.get(), &QLocalServer::newConnection,
 | 
			
		||||
            this, &KDSingleApplicationLocalSocket::handleNewConnection);
 | 
			
		||||
 | 
			
		||||
    m_lockFile = std::move(lockFile);
 | 
			
		||||
    m_localServer = std::move(server);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
KDSingleApplicationLocalSocket::~KDSingleApplicationLocalSocket() = default;
 | 
			
		||||
 | 
			
		||||
bool KDSingleApplicationLocalSocket::isPrimaryInstance() const
 | 
			
		||||
{
 | 
			
		||||
    return m_localServer != nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool KDSingleApplicationLocalSocket::sendMessage(const QByteArray &message, int timeout)
 | 
			
		||||
{
 | 
			
		||||
    Q_ASSERT(!isPrimaryInstance());
 | 
			
		||||
    QLocalSocket socket;
 | 
			
		||||
 | 
			
		||||
    qCDebug(kdsaLocalSocket) << "Preparing to send message" << message << "with timeout" << timeout;
 | 
			
		||||
 | 
			
		||||
    QDeadlineTimer deadline(timeout);
 | 
			
		||||
 | 
			
		||||
    // There is an inherent race here with the setup of the server side.
 | 
			
		||||
    // Even if the socket lock is held by the server, the server may not
 | 
			
		||||
    // be listening yet. So this connection may fail; keep retrying
 | 
			
		||||
    // until we hit the timeout.
 | 
			
		||||
    do {
 | 
			
		||||
        socket.connectToServer(m_socketName);
 | 
			
		||||
        if (socket.waitForConnected(deadline.remainingTime()))
 | 
			
		||||
            break;
 | 
			
		||||
    } while (!deadline.hasExpired());
 | 
			
		||||
 | 
			
		||||
    qCDebug(kdsaLocalSocket) << "Socket state:" << socket.state() << "Timer remaining" << deadline.remainingTime() << "Expired?" << deadline.hasExpired();
 | 
			
		||||
 | 
			
		||||
    if (deadline.hasExpired())
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
    socket.write(&LOCALSOCKET_PROTOCOL_VERSION, 1);
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        QByteArray encodedMessage;
 | 
			
		||||
        QDataStream ds(&encodedMessage, QIODevice::WriteOnly);
 | 
			
		||||
        ds << message;
 | 
			
		||||
        socket.write(encodedMessage);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    qCDebug(kdsaLocalSocket) << "Wrote message in the socket" << "Timer remaining" << deadline.remainingTime() << "Expired?" << deadline.hasExpired();
 | 
			
		||||
 | 
			
		||||
    // There is no acknowledgement mechanism here.
 | 
			
		||||
    // Should there be one?
 | 
			
		||||
 | 
			
		||||
    while (socket.bytesToWrite() > 0) {
 | 
			
		||||
        if (!socket.waitForBytesWritten(deadline.remainingTime()))
 | 
			
		||||
            return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    qCDebug(kdsaLocalSocket) << "Bytes written, now disconnecting" << "Timer remaining" << deadline.remainingTime() << "Expired?" << deadline.hasExpired();
 | 
			
		||||
 | 
			
		||||
    socket.disconnectFromServer();
 | 
			
		||||
 | 
			
		||||
    if (socket.state() == QLocalSocket::UnconnectedState)
 | 
			
		||||
        return true;
 | 
			
		||||
 | 
			
		||||
    if (!socket.waitForDisconnected(deadline.remainingTime()))
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
    qCDebug(kdsaLocalSocket) << "Disconnected -- success!";
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KDSingleApplicationLocalSocket::handleNewConnection()
 | 
			
		||||
{
 | 
			
		||||
    Q_ASSERT(m_localServer);
 | 
			
		||||
 | 
			
		||||
    QLocalSocket *socket = m_localServer->nextPendingConnection();
 | 
			
		||||
 | 
			
		||||
    qCDebug(kdsaLocalSocket) << "Got new connection on" << m_socketName << "state" << socket->state();
 | 
			
		||||
 | 
			
		||||
    Connection c(socket);
 | 
			
		||||
 | 
			
		||||
    c.readDataConnection = QObjectConnectionHolder(
 | 
			
		||||
                connect(c.socket.get(), &QLocalSocket::readyRead,
 | 
			
		||||
                        this, &KDSingleApplicationLocalSocket::readDataFromSecondary));
 | 
			
		||||
 | 
			
		||||
    c.secondaryDisconnectedConnection = QObjectConnectionHolder(
 | 
			
		||||
                connect(c.socket.get(), &QLocalSocket::disconnected,
 | 
			
		||||
                        this, &KDSingleApplicationLocalSocket::secondaryDisconnected));
 | 
			
		||||
 | 
			
		||||
    c.abortConnection = QObjectConnectionHolder(
 | 
			
		||||
                connect(c.timeoutTimer.get(), &QTimer::timeout,
 | 
			
		||||
                        this, &KDSingleApplicationLocalSocket::abortConnectionToSecondary));
 | 
			
		||||
 | 
			
		||||
    m_clients.push_back(std::move(c));
 | 
			
		||||
 | 
			
		||||
    // Note that by the time we get here, the socket could've already been closed,
 | 
			
		||||
    // and no signals emitted (hello, Windows!). Read what's already in the socket.
 | 
			
		||||
    if (readDataFromSecondarySocket(socket))
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    if (socket->state() == QLocalSocket::UnconnectedState)
 | 
			
		||||
        secondarySocketDisconnected(socket);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Container>
 | 
			
		||||
static auto findConnectionBySocket(Container &container, QLocalSocket *socket)
 | 
			
		||||
{
 | 
			
		||||
    auto i = std::find_if(container.begin(),
 | 
			
		||||
                          container.end(),
 | 
			
		||||
                          [socket](const auto &c) { return c.socket.get() == socket; });
 | 
			
		||||
    Q_ASSERT(i != container.end());
 | 
			
		||||
    return i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Container>
 | 
			
		||||
static auto findConnectionByTimer(Container &container, QTimer *timer)
 | 
			
		||||
{
 | 
			
		||||
    auto i = std::find_if(container.begin(),
 | 
			
		||||
                          container.end(),
 | 
			
		||||
                          [timer](const auto &c) { return c.timeoutTimer.get() == timer; });
 | 
			
		||||
    Q_ASSERT(i != container.end());
 | 
			
		||||
    return i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KDSingleApplicationLocalSocket::readDataFromSecondary()
 | 
			
		||||
{
 | 
			
		||||
    QLocalSocket *socket = static_cast<QLocalSocket *>(sender());
 | 
			
		||||
    readDataFromSecondarySocket(socket);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool KDSingleApplicationLocalSocket::readDataFromSecondarySocket(QLocalSocket *socket)
 | 
			
		||||
{
 | 
			
		||||
    auto i = findConnectionBySocket(m_clients, socket);
 | 
			
		||||
    Connection &c = *i;
 | 
			
		||||
    c.readData.append(socket->readAll());
 | 
			
		||||
 | 
			
		||||
    qCDebug(kdsaLocalSocket) << "Got more data from a secondary. Data read so far:" << c.readData;
 | 
			
		||||
 | 
			
		||||
    const QByteArray &data = c.readData;
 | 
			
		||||
 | 
			
		||||
    if (data.size() >= 1) {
 | 
			
		||||
        if (data[0] != LOCALSOCKET_PROTOCOL_VERSION) {
 | 
			
		||||
            qCDebug(kdsaLocalSocket) << "Got an invalid protocol version";
 | 
			
		||||
            m_clients.erase(i);
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    QDataStream ds(data);
 | 
			
		||||
    ds.skipRawData(1);
 | 
			
		||||
 | 
			
		||||
    ds.startTransaction();
 | 
			
		||||
    QByteArray message;
 | 
			
		||||
    ds >> message;
 | 
			
		||||
 | 
			
		||||
    if (ds.commitTransaction()) {
 | 
			
		||||
        qCDebug(kdsaLocalSocket) << "Got a complete message:" << message;
 | 
			
		||||
        Q_EMIT messageReceived(message);
 | 
			
		||||
        m_clients.erase(i);
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KDSingleApplicationLocalSocket::secondaryDisconnected()
 | 
			
		||||
{
 | 
			
		||||
    QLocalSocket *socket = static_cast<QLocalSocket *>(sender());
 | 
			
		||||
    secondarySocketDisconnected(socket);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KDSingleApplicationLocalSocket::secondarySocketDisconnected(QLocalSocket *socket)
 | 
			
		||||
{
 | 
			
		||||
    auto i = findConnectionBySocket(m_clients, socket);
 | 
			
		||||
    Connection c = std::move(*i);
 | 
			
		||||
    m_clients.erase(i);
 | 
			
		||||
 | 
			
		||||
    qCDebug(kdsaLocalSocket) << "Secondary disconnected. Data read:" << c.readData;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KDSingleApplicationLocalSocket::abortConnectionToSecondary()
 | 
			
		||||
{
 | 
			
		||||
    QTimer *timer = static_cast<QTimer *>(sender());
 | 
			
		||||
 | 
			
		||||
    auto i = findConnectionByTimer(m_clients, timer);
 | 
			
		||||
    Connection c = std::move(*i);
 | 
			
		||||
    m_clients.erase(i);
 | 
			
		||||
 | 
			
		||||
    qCDebug(kdsaLocalSocket) << "Secondary timed out. Data read:" << c.readData;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
KDSingleApplicationLocalSocket::Connection::Connection(QLocalSocket *socket)
 | 
			
		||||
    : socket(socket)
 | 
			
		||||
    , timeoutTimer(new QTimer)
 | 
			
		||||
{
 | 
			
		||||
    timeoutTimer->start(LOCALSOCKET_CONNECTION_TIMEOUT);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										133
									
								
								3rdparty/kdsingleapplication/kdsingleapplication_localsocket_p.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								3rdparty/kdsingleapplication/kdsingleapplication_localsocket_p.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,133 @@
 | 
			
		||||
/*
 | 
			
		||||
    MIT License
 | 
			
		||||
 | 
			
		||||
    Copyright (C) 2019-2021 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
 | 
			
		||||
 | 
			
		||||
    Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
    of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
    in the Software without restriction, including without limitation the rights
 | 
			
		||||
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
    copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
    furnished to do so, subject to the following conditions:
 | 
			
		||||
 | 
			
		||||
    The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
    copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
    SOFTWARE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef KDSINGLEAPPLICATION_LOCALSOCKET_P_H
 | 
			
		||||
#define KDSINGLEAPPLICATION_LOCALSOCKET_P_H
 | 
			
		||||
 | 
			
		||||
#include <QtCore/QObject>
 | 
			
		||||
#include <QtCore/QByteArray>
 | 
			
		||||
#include <QtCore/QString>
 | 
			
		||||
 | 
			
		||||
QT_BEGIN_NAMESPACE
 | 
			
		||||
class QLockFile;
 | 
			
		||||
class QLocalServer;
 | 
			
		||||
class QLocalSocket;
 | 
			
		||||
class QTimer;
 | 
			
		||||
QT_END_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
struct QObjectDeleteLater
 | 
			
		||||
{
 | 
			
		||||
    void operator()(QObject *o) { o->deleteLater(); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class QObjectConnectionHolder
 | 
			
		||||
{
 | 
			
		||||
    Q_DISABLE_COPY(QObjectConnectionHolder)
 | 
			
		||||
    QMetaObject::Connection c;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    QObjectConnectionHolder() {}
 | 
			
		||||
 | 
			
		||||
    explicit QObjectConnectionHolder(QMetaObject::Connection c)
 | 
			
		||||
        : c(std::move(c))
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~QObjectConnectionHolder()
 | 
			
		||||
    {
 | 
			
		||||
        QObject::disconnect(c);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    QObjectConnectionHolder(QObjectConnectionHolder &&other) noexcept
 | 
			
		||||
        : c(std::exchange(other.c, {}))
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
    QObjectConnectionHolder &operator=(QObjectConnectionHolder &&other) noexcept
 | 
			
		||||
    {
 | 
			
		||||
        QObjectConnectionHolder moved(std::move(other));
 | 
			
		||||
        swap(moved);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void swap(QObjectConnectionHolder &other) noexcept
 | 
			
		||||
    {
 | 
			
		||||
        using std::swap;
 | 
			
		||||
        swap(c, other.c);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class KDSingleApplicationLocalSocket : public QObject
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    explicit KDSingleApplicationLocalSocket(const QString &name,
 | 
			
		||||
                                            QObject *parent = nullptr);
 | 
			
		||||
    ~KDSingleApplicationLocalSocket();
 | 
			
		||||
 | 
			
		||||
    bool isPrimaryInstance() const;
 | 
			
		||||
 | 
			
		||||
public Q_SLOTS:
 | 
			
		||||
    bool sendMessage(const QByteArray &message, int timeout);
 | 
			
		||||
 | 
			
		||||
Q_SIGNALS:
 | 
			
		||||
    void messageReceived(const QByteArray &message);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    void handleNewConnection();
 | 
			
		||||
    void readDataFromSecondary();
 | 
			
		||||
    bool readDataFromSecondarySocket(QLocalSocket *socket);
 | 
			
		||||
    void secondaryDisconnected();
 | 
			
		||||
    void secondarySocketDisconnected(QLocalSocket *socket);
 | 
			
		||||
    void abortConnectionToSecondary();
 | 
			
		||||
 | 
			
		||||
    QString m_socketName;
 | 
			
		||||
 | 
			
		||||
    std::unique_ptr<QLockFile> m_lockFile; // protects m_localServer
 | 
			
		||||
    std::unique_ptr<QLocalServer> m_localServer;
 | 
			
		||||
 | 
			
		||||
    struct Connection {
 | 
			
		||||
        explicit Connection(QLocalSocket *s);
 | 
			
		||||
 | 
			
		||||
        std::unique_ptr<QLocalSocket, QObjectDeleteLater> socket;
 | 
			
		||||
        std::unique_ptr<QTimer, QObjectDeleteLater> timeoutTimer;
 | 
			
		||||
        QByteArray readData;
 | 
			
		||||
 | 
			
		||||
        // socket/timeoutTimer are deleted via deleteLater (as we delete them
 | 
			
		||||
        // in slots connected to their signals). Before the deleteLater is acted upon,
 | 
			
		||||
        // they may emit further signals, triggering logic that it's not supposed
 | 
			
		||||
        // to be triggered (as the Connection has already been destroyed).
 | 
			
		||||
        // Use this Holder to break the connections.
 | 
			
		||||
        QObjectConnectionHolder readDataConnection;
 | 
			
		||||
        QObjectConnectionHolder secondaryDisconnectedConnection;
 | 
			
		||||
        QObjectConnectionHolder abortConnection;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    std::vector<Connection> m_clients;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // KDSINGLEAPPLICATION_LOCALSOCKET_P_H
 | 
			
		||||
							
								
								
									
										20
									
								
								3rdparty/kdsingleapplication/src.pro
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								3rdparty/kdsingleapplication/src.pro
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
include(../common.pri)
 | 
			
		||||
 | 
			
		||||
TEMPLATE = lib
 | 
			
		||||
TARGET = kdsingleapplication
 | 
			
		||||
QT = core network
 | 
			
		||||
CONFIG += static
 | 
			
		||||
 | 
			
		||||
SOURCES += \
 | 
			
		||||
    kdsingleapplication.cpp \
 | 
			
		||||
    kdsingleapplication_localsocket.cpp \
 | 
			
		||||
 | 
			
		||||
HEADERS += \
 | 
			
		||||
    kdsingleapplication.h \
 | 
			
		||||
    kdsingleapplication_lib.h \
 | 
			
		||||
    kdsingleapplication_localsocket_p.h \
 | 
			
		||||
 | 
			
		||||
DEFINES += \
 | 
			
		||||
    KDSINGLEAPPLICATION_BUILD
 | 
			
		||||
 | 
			
		||||
win32:LIBS += -lkernel32
 | 
			
		||||
							
								
								
									
										488
									
								
								3rdparty/kdsingleapplicationguard/LICENSE.LGPL.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										488
									
								
								3rdparty/kdsingleapplicationguard/LICENSE.LGPL.txt
									
									
									
									
										vendored
									
									
								
							@@ -1,488 +0,0 @@
 | 
			
		||||
 | 
			
		||||
 The KD Tools Library is Copyright (C) 2001-2010 Klaralvdalens Datakonsult AB.
 | 
			
		||||
 | 
			
		||||
 You may use, distribute and copy the KD Tools Library under the terms of
 | 
			
		||||
 GNU Library General Public License version 2, which is displayed below.
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------------
 | 
			
		||||
                  GNU LIBRARY GENERAL PUBLIC LICENSE
 | 
			
		||||
                       Version 2, June 1991
 | 
			
		||||
 | 
			
		||||
 Copyright (C) 1991 Free Software Foundation, Inc.
 | 
			
		||||
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
 Everyone is permitted to copy and distribute verbatim copies
 | 
			
		||||
 of this license document, but changing it is not allowed.
 | 
			
		||||
 | 
			
		||||
[This is the first released version of the library GPL.  It is
 | 
			
		||||
 numbered 2 because it goes with version 2 of the ordinary GPL.]
 | 
			
		||||
 | 
			
		||||
                            Preamble
 | 
			
		||||
 | 
			
		||||
  The licenses for most software are designed to take away your
 | 
			
		||||
freedom to share and change it.  By contrast, the GNU General Public
 | 
			
		||||
Licenses are intended to guarantee your freedom to share and change
 | 
			
		||||
free software--to make sure the software is free for all its users.
 | 
			
		||||
 | 
			
		||||
  This license, the Library General Public License, applies to some
 | 
			
		||||
specially designated Free Software Foundation software, and to any
 | 
			
		||||
other libraries whose authors decide to use it.  You can use it for
 | 
			
		||||
your libraries, too.
 | 
			
		||||
 | 
			
		||||
  When we speak of free software, we are referring to freedom, not
 | 
			
		||||
price.  Our General Public Licenses are designed to make sure that you
 | 
			
		||||
have the freedom to distribute copies of free software (and charge for
 | 
			
		||||
this service if you wish), that you receive source code or can get it
 | 
			
		||||
if you want it, that you can change the software or use pieces of it
 | 
			
		||||
in new free programs; and that you know you can do these things.
 | 
			
		||||
 | 
			
		||||
  To protect your rights, we need to make restrictions that forbid
 | 
			
		||||
anyone to deny you these rights or to ask you to surrender the rights.
 | 
			
		||||
These restrictions translate to certain responsibilities for you if
 | 
			
		||||
you distribute copies of the library, or if you modify it.
 | 
			
		||||
 | 
			
		||||
  For example, if you distribute copies of the library, whether gratis
 | 
			
		||||
or for a fee, you must give the recipients all the rights that we gave
 | 
			
		||||
you.  You must make sure that they, too, receive or can get the source
 | 
			
		||||
code.  If you link a program with the library, you must provide
 | 
			
		||||
complete object files to the recipients so that they can relink them
 | 
			
		||||
with the library, after making changes to the library and recompiling
 | 
			
		||||
it.  And you must show them these terms so they know their rights.
 | 
			
		||||
 | 
			
		||||
  Our method of protecting your rights has two steps: (1) copyright
 | 
			
		||||
the library, and (2) offer you this license which gives you legal
 | 
			
		||||
permission to copy, distribute and/or modify the library.
 | 
			
		||||
 | 
			
		||||
  Also, for each distributor's protection, we want to make certain
 | 
			
		||||
that everyone understands that there is no warranty for this free
 | 
			
		||||
library.  If the library is modified by someone else and passed on, we
 | 
			
		||||
want its recipients to know that what they have is not the original
 | 
			
		||||
version, so that any problems introduced by others will not reflect on
 | 
			
		||||
the original authors' reputations.
 | 
			
		||||
 | 
			
		||||
  Finally, any free program is threatened constantly by software
 | 
			
		||||
patents.  We wish to avoid the danger that companies distributing free
 | 
			
		||||
software will individually obtain patent licenses, thus in effect
 | 
			
		||||
transforming the program into proprietary software.  To prevent this,
 | 
			
		||||
we have made it clear that any patent must be licensed for everyone's
 | 
			
		||||
free use or not licensed at all.
 | 
			
		||||
 | 
			
		||||
  Most GNU software, including some libraries, is covered by the ordinary
 | 
			
		||||
GNU General Public License, which was designed for utility programs.  This
 | 
			
		||||
license, the GNU Library General Public License, applies to certain
 | 
			
		||||
designated libraries.  This license is quite different from the ordinary
 | 
			
		||||
one; be sure to read it in full, and don't assume that anything in it is
 | 
			
		||||
the same as in the ordinary license.
 | 
			
		||||
 | 
			
		||||
  The reason we have a separate public license for some libraries is that
 | 
			
		||||
they blur the distinction we usually make between modifying or adding to a
 | 
			
		||||
program and simply using it.  Linking a program with a library, without
 | 
			
		||||
changing the library, is in some sense simply using the library, and is
 | 
			
		||||
analogous to running a utility program or application program.  However, in
 | 
			
		||||
a textual and legal sense, the linked executable is a combined work, a
 | 
			
		||||
derivative of the original library, and the ordinary General Public License
 | 
			
		||||
treats it as such.
 | 
			
		||||
 | 
			
		||||
  Because of this blurred distinction, using the ordinary General
 | 
			
		||||
Public License for libraries did not effectively promote software
 | 
			
		||||
sharing, because most developers did not use the libraries.  We
 | 
			
		||||
concluded that weaker conditions might promote sharing better.
 | 
			
		||||
 | 
			
		||||
  However, unrestricted linking of non-free programs would deprive the
 | 
			
		||||
users of those programs of all benefit from the free status of the
 | 
			
		||||
libraries themselves.  This Library General Public License is intended to
 | 
			
		||||
permit developers of non-free programs to use free libraries, while
 | 
			
		||||
preserving your freedom as a user of such programs to change the free
 | 
			
		||||
libraries that are incorporated in them.  (We have not seen how to achieve
 | 
			
		||||
this as regards changes in header files, but we have achieved it as regards
 | 
			
		||||
changes in the actual functions of the Library.)  The hope is that this
 | 
			
		||||
will lead to faster development of free libraries.
 | 
			
		||||
 | 
			
		||||
  The precise terms and conditions for copying, distribution and
 | 
			
		||||
modification follow.  Pay close attention to the difference between a
 | 
			
		||||
"work based on the library" and a "work that uses the library".  The
 | 
			
		||||
former contains code derived from the library, while the latter only
 | 
			
		||||
works together with the library.
 | 
			
		||||
 | 
			
		||||
  Note that it is possible for a library to be covered by the ordinary
 | 
			
		||||
General Public License rather than by this special one.
 | 
			
		||||
 | 
			
		||||
                  GNU LIBRARY GENERAL PUBLIC LICENSE
 | 
			
		||||
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 | 
			
		||||
 | 
			
		||||
  0. This License Agreement applies to any software library which
 | 
			
		||||
contains a notice placed by the copyright holder or other authorized
 | 
			
		||||
party saying it may be distributed under the terms of this Library
 | 
			
		||||
General Public License (also called "this License").  Each licensee is
 | 
			
		||||
addressed as "you".
 | 
			
		||||
 | 
			
		||||
  A "library" means a collection of software functions and/or data
 | 
			
		||||
prepared so as to be conveniently linked with application programs
 | 
			
		||||
(which use some of those functions and data) to form executables.
 | 
			
		||||
 | 
			
		||||
  The "Library", below, refers to any such software library or work
 | 
			
		||||
which has been distributed under these terms.  A "work based on the
 | 
			
		||||
Library" means either the Library or any derivative work under
 | 
			
		||||
copyright law: that is to say, a work containing the Library or a
 | 
			
		||||
portion of it, either verbatim or with modifications and/or translated
 | 
			
		||||
straightforwardly into another language.  (Hereinafter, translation is
 | 
			
		||||
included without limitation in the term "modification".)
 | 
			
		||||
 | 
			
		||||
  "Source code" for a work means the preferred form of the work for
 | 
			
		||||
making modifications to it.  For a library, complete source code means
 | 
			
		||||
all the source code for all modules it contains, plus any associated
 | 
			
		||||
interface definition files, plus the scripts used to control compilation
 | 
			
		||||
and installation of the library.
 | 
			
		||||
 | 
			
		||||
  Activities other than copying, distribution and modification are not
 | 
			
		||||
covered by this License; they are outside its scope.  The act of
 | 
			
		||||
running a program using the Library is not restricted, and output from
 | 
			
		||||
such a program is covered only if its contents constitute a work based
 | 
			
		||||
on the Library (independent of the use of the Library in a tool for
 | 
			
		||||
writing it).  Whether that is true depends on what the Library does
 | 
			
		||||
and what the program that uses the Library does.
 | 
			
		||||
  
 | 
			
		||||
  1. You may copy and distribute verbatim copies of the Library's
 | 
			
		||||
complete source code as you receive it, in any medium, provided that
 | 
			
		||||
you conspicuously and appropriately publish on each copy an
 | 
			
		||||
appropriate copyright notice and disclaimer of warranty; keep intact
 | 
			
		||||
all the notices that refer to this License and to the absence of any
 | 
			
		||||
warranty; and distribute a copy of this License along with the
 | 
			
		||||
Library.
 | 
			
		||||
 | 
			
		||||
  You may charge a fee for the physical act of transferring a copy,
 | 
			
		||||
and you may at your option offer warranty protection in exchange for a
 | 
			
		||||
fee.
 | 
			
		||||
 | 
			
		||||
  2. You may modify your copy or copies of the Library or any portion
 | 
			
		||||
of it, thus forming a work based on the Library, and copy and
 | 
			
		||||
distribute such modifications or work under the terms of Section 1
 | 
			
		||||
above, provided that you also meet all of these conditions:
 | 
			
		||||
 | 
			
		||||
    a) The modified work must itself be a software library.
 | 
			
		||||
 | 
			
		||||
    b) You must cause the files modified to carry prominent notices
 | 
			
		||||
    stating that you changed the files and the date of any change.
 | 
			
		||||
 | 
			
		||||
    c) You must cause the whole of the work to be licensed at no
 | 
			
		||||
    charge to all third parties under the terms of this License.
 | 
			
		||||
 | 
			
		||||
    d) If a facility in the modified Library refers to a function or a
 | 
			
		||||
    table of data to be supplied by an application program that uses
 | 
			
		||||
    the facility, other than as an argument passed when the facility
 | 
			
		||||
    is invoked, then you must make a good faith effort to ensure that,
 | 
			
		||||
    in the event an application does not supply such function or
 | 
			
		||||
    table, the facility still operates, and performs whatever part of
 | 
			
		||||
    its purpose remains meaningful.
 | 
			
		||||
 | 
			
		||||
    (For example, a function in a library to compute square roots has
 | 
			
		||||
    a purpose that is entirely well-defined independent of the
 | 
			
		||||
    application.  Therefore, Subsection 2d requires that any
 | 
			
		||||
    application-supplied function or table used by this function must
 | 
			
		||||
    be optional: if the application does not supply it, the square
 | 
			
		||||
    root function must still compute square roots.)
 | 
			
		||||
 | 
			
		||||
These requirements apply to the modified work as a whole.  If
 | 
			
		||||
identifiable sections of that work are not derived from the Library,
 | 
			
		||||
and can be reasonably considered independent and separate works in
 | 
			
		||||
themselves, then this License, and its terms, do not apply to those
 | 
			
		||||
sections when you distribute them as separate works.  But when you
 | 
			
		||||
distribute the same sections as part of a whole which is a work based
 | 
			
		||||
on the Library, the distribution of the whole must be on the terms of
 | 
			
		||||
this License, whose permissions for other licensees extend to the
 | 
			
		||||
entire whole, and thus to each and every part regardless of who wrote
 | 
			
		||||
it.
 | 
			
		||||
 | 
			
		||||
Thus, it is not the intent of this section to claim rights or contest
 | 
			
		||||
your rights to work written entirely by you; rather, the intent is to
 | 
			
		||||
exercise the right to control the distribution of derivative or
 | 
			
		||||
collective works based on the Library.
 | 
			
		||||
 | 
			
		||||
In addition, mere aggregation of another work not based on the Library
 | 
			
		||||
with the Library (or with a work based on the Library) on a volume of
 | 
			
		||||
a storage or distribution medium does not bring the other work under
 | 
			
		||||
the scope of this License.
 | 
			
		||||
 | 
			
		||||
  3. You may opt to apply the terms of the ordinary GNU General Public
 | 
			
		||||
License instead of this License to a given copy of the Library.  To do
 | 
			
		||||
this, you must alter all the notices that refer to this License, so
 | 
			
		||||
that they refer to the ordinary GNU General Public License, version 2,
 | 
			
		||||
instead of to this License.  (If a newer version than version 2 of the
 | 
			
		||||
ordinary GNU General Public License has appeared, then you can specify
 | 
			
		||||
that version instead if you wish.)  Do not make any other change in
 | 
			
		||||
these notices.
 | 
			
		||||
 | 
			
		||||
  Once this change is made in a given copy, it is irreversible for
 | 
			
		||||
that copy, so the ordinary GNU General Public License applies to all
 | 
			
		||||
subsequent copies and derivative works made from that copy.
 | 
			
		||||
 | 
			
		||||
  This option is useful when you wish to copy part of the code of
 | 
			
		||||
the Library into a program that is not a library.
 | 
			
		||||
 | 
			
		||||
  4. You may copy and distribute the Library (or a portion or
 | 
			
		||||
derivative of it, under Section 2) in object code or executable form
 | 
			
		||||
under the terms of Sections 1 and 2 above provided that you accompany
 | 
			
		||||
it with the complete corresponding machine-readable source code, which
 | 
			
		||||
must be distributed under the terms of Sections 1 and 2 above on a
 | 
			
		||||
medium customarily used for software interchange.
 | 
			
		||||
 | 
			
		||||
  If distribution of object code is made by offering access to copy
 | 
			
		||||
from a designated place, then offering equivalent access to copy the
 | 
			
		||||
source code from the same place satisfies the requirement to
 | 
			
		||||
distribute the source code, even though third parties are not
 | 
			
		||||
compelled to copy the source along with the object code.
 | 
			
		||||
 | 
			
		||||
  5. A program that contains no derivative of any portion of the
 | 
			
		||||
Library, but is designed to work with the Library by being compiled or
 | 
			
		||||
linked with it, is called a "work that uses the Library".  Such a
 | 
			
		||||
work, in isolation, is not a derivative work of the Library, and
 | 
			
		||||
therefore falls outside the scope of this License.
 | 
			
		||||
 | 
			
		||||
  However, linking a "work that uses the Library" with the Library
 | 
			
		||||
creates an executable that is a derivative of the Library (because it
 | 
			
		||||
contains portions of the Library), rather than a "work that uses the
 | 
			
		||||
library".  The executable is therefore covered by this License.
 | 
			
		||||
Section 6 states terms for distribution of such executables.
 | 
			
		||||
 | 
			
		||||
  When a "work that uses the Library" uses material from a header file
 | 
			
		||||
that is part of the Library, the object code for the work may be a
 | 
			
		||||
derivative work of the Library even though the source code is not.
 | 
			
		||||
Whether this is true is especially significant if the work can be
 | 
			
		||||
linked without the Library, or if the work is itself a library.  The
 | 
			
		||||
threshold for this to be true is not precisely defined by law.
 | 
			
		||||
 | 
			
		||||
  If such an object file uses only numerical parameters, data
 | 
			
		||||
structure layouts and accessors, and small macros and small inline
 | 
			
		||||
functions (ten lines or less in length), then the use of the object
 | 
			
		||||
file is unrestricted, regardless of whether it is legally a derivative
 | 
			
		||||
work.  (Executables containing this object code plus portions of the
 | 
			
		||||
Library will still fall under Section 6.)
 | 
			
		||||
 | 
			
		||||
  Otherwise, if the work is a derivative of the Library, you may
 | 
			
		||||
distribute the object code for the work under the terms of Section 6.
 | 
			
		||||
Any executables containing that work also fall under Section 6,
 | 
			
		||||
whether or not they are linked directly with the Library itself.
 | 
			
		||||
 | 
			
		||||
  6. As an exception to the Sections above, you may also compile or
 | 
			
		||||
link a "work that uses the Library" with the Library to produce a
 | 
			
		||||
work containing portions of the Library, and distribute that work
 | 
			
		||||
under terms of your choice, provided that the terms permit
 | 
			
		||||
modification of the work for the customer's own use and reverse
 | 
			
		||||
engineering for debugging such modifications.
 | 
			
		||||
 | 
			
		||||
  You must give prominent notice with each copy of the work that the
 | 
			
		||||
Library is used in it and that the Library and its use are covered by
 | 
			
		||||
this License.  You must supply a copy of this License.  If the work
 | 
			
		||||
during execution displays copyright notices, you must include the
 | 
			
		||||
copyright notice for the Library among them, as well as a reference
 | 
			
		||||
directing the user to the copy of this License.  Also, you must do one
 | 
			
		||||
of these things:
 | 
			
		||||
 | 
			
		||||
    a) Accompany the work with the complete corresponding
 | 
			
		||||
    machine-readable source code for the Library including whatever
 | 
			
		||||
    changes were used in the work (which must be distributed under
 | 
			
		||||
    Sections 1 and 2 above); and, if the work is an executable linked
 | 
			
		||||
    with the Library, with the complete machine-readable "work that
 | 
			
		||||
    uses the Library", as object code and/or source code, so that the
 | 
			
		||||
    user can modify the Library and then relink to produce a modified
 | 
			
		||||
    executable containing the modified Library.  (It is understood
 | 
			
		||||
    that the user who changes the contents of definitions files in the
 | 
			
		||||
    Library will not necessarily be able to recompile the application
 | 
			
		||||
    to use the modified definitions.)
 | 
			
		||||
 | 
			
		||||
    b) Accompany the work with a written offer, valid for at
 | 
			
		||||
    least three years, to give the same user the materials
 | 
			
		||||
    specified in Subsection 6a, above, for a charge no more
 | 
			
		||||
    than the cost of performing this distribution.
 | 
			
		||||
 | 
			
		||||
    c) If distribution of the work is made by offering access to copy
 | 
			
		||||
    from a designated place, offer equivalent access to copy the above
 | 
			
		||||
    specified materials from the same place.
 | 
			
		||||
 | 
			
		||||
    d) Verify that the user has already received a copy of these
 | 
			
		||||
    materials or that you have already sent this user a copy.
 | 
			
		||||
 | 
			
		||||
  For an executable, the required form of the "work that uses the
 | 
			
		||||
Library" must include any data and utility programs needed for
 | 
			
		||||
reproducing the executable from it.  However, as a special exception,
 | 
			
		||||
the source code distributed need not include anything that is normally
 | 
			
		||||
distributed (in either source or binary form) with the major
 | 
			
		||||
components (compiler, kernel, and so on) of the operating system on
 | 
			
		||||
which the executable runs, unless that component itself accompanies
 | 
			
		||||
the executable.
 | 
			
		||||
 | 
			
		||||
  It may happen that this requirement contradicts the license
 | 
			
		||||
restrictions of other proprietary libraries that do not normally
 | 
			
		||||
accompany the operating system.  Such a contradiction means you cannot
 | 
			
		||||
use both them and the Library together in an executable that you
 | 
			
		||||
distribute.
 | 
			
		||||
 | 
			
		||||
  7. You may place library facilities that are a work based on the
 | 
			
		||||
Library side-by-side in a single library together with other library
 | 
			
		||||
facilities not covered by this License, and distribute such a combined
 | 
			
		||||
library, provided that the separate distribution of the work based on
 | 
			
		||||
the Library and of the other library facilities is otherwise
 | 
			
		||||
permitted, and provided that you do these two things:
 | 
			
		||||
 | 
			
		||||
    a) Accompany the combined library with a copy of the same work
 | 
			
		||||
    based on the Library, uncombined with any other library
 | 
			
		||||
    facilities.  This must be distributed under the terms of the
 | 
			
		||||
    Sections above.
 | 
			
		||||
 | 
			
		||||
    b) Give prominent notice with the combined library of the fact
 | 
			
		||||
    that part of it is a work based on the Library, and explaining
 | 
			
		||||
    where to find the accompanying uncombined form of the same work.
 | 
			
		||||
 | 
			
		||||
  8. You may not copy, modify, sublicense, link with, or distribute
 | 
			
		||||
the Library except as expressly provided under this License.  Any
 | 
			
		||||
attempt otherwise to copy, modify, sublicense, link with, or
 | 
			
		||||
distribute the Library is void, and will automatically terminate your
 | 
			
		||||
rights under this License.  However, parties who have received copies,
 | 
			
		||||
or rights, from you under this License will not have their licenses
 | 
			
		||||
terminated so long as such parties remain in full compliance.
 | 
			
		||||
 | 
			
		||||
  9. You are not required to accept this License, since you have not
 | 
			
		||||
signed it.  However, nothing else grants you permission to modify or
 | 
			
		||||
distribute the Library or its derivative works.  These actions are
 | 
			
		||||
prohibited by law if you do not accept this License.  Therefore, by
 | 
			
		||||
modifying or distributing the Library (or any work based on the
 | 
			
		||||
Library), you indicate your acceptance of this License to do so, and
 | 
			
		||||
all its terms and conditions for copying, distributing or modifying
 | 
			
		||||
the Library or works based on it.
 | 
			
		||||
 | 
			
		||||
  10. Each time you redistribute the Library (or any work based on the
 | 
			
		||||
Library), the recipient automatically receives a license from the
 | 
			
		||||
original licensor to copy, distribute, link with or modify the Library
 | 
			
		||||
subject to these terms and conditions.  You may not impose any further
 | 
			
		||||
restrictions on the recipients' exercise of the rights granted herein.
 | 
			
		||||
You are not responsible for enforcing compliance by third parties to
 | 
			
		||||
this License.
 | 
			
		||||
 | 
			
		||||
  11. If, as a consequence of a court judgment or allegation of patent
 | 
			
		||||
infringement or for any other reason (not limited to patent issues),
 | 
			
		||||
conditions are imposed on you (whether by court order, agreement or
 | 
			
		||||
otherwise) that contradict the conditions of this License, they do not
 | 
			
		||||
excuse you from the conditions of this License.  If you cannot
 | 
			
		||||
distribute so as to satisfy simultaneously your obligations under this
 | 
			
		||||
License and any other pertinent obligations, then as a consequence you
 | 
			
		||||
may not distribute the Library at all.  For example, if a patent
 | 
			
		||||
license would not permit royalty-free redistribution of the Library by
 | 
			
		||||
all those who receive copies directly or indirectly through you, then
 | 
			
		||||
the only way you could satisfy both it and this License would be to
 | 
			
		||||
refrain entirely from distribution of the Library.
 | 
			
		||||
 | 
			
		||||
If any portion of this section is held invalid or unenforceable under any
 | 
			
		||||
particular circumstance, the balance of the section is intended to apply,
 | 
			
		||||
and the section as a whole is intended to apply in other circumstances.
 | 
			
		||||
 | 
			
		||||
It is not the purpose of this section to induce you to infringe any
 | 
			
		||||
patents or other property right claims or to contest validity of any
 | 
			
		||||
such claims; this section has the sole purpose of protecting the
 | 
			
		||||
integrity of the free software distribution system which is
 | 
			
		||||
implemented by public license practices.  Many people have made
 | 
			
		||||
generous contributions to the wide range of software distributed
 | 
			
		||||
through that system in reliance on consistent application of that
 | 
			
		||||
system; it is up to the author/donor to decide if he or she is willing
 | 
			
		||||
to distribute software through any other system and a licensee cannot
 | 
			
		||||
impose that choice.
 | 
			
		||||
 | 
			
		||||
This section is intended to make thoroughly clear what is believed to
 | 
			
		||||
be a consequence of the rest of this License.
 | 
			
		||||
 | 
			
		||||
  12. If the distribution and/or use of the Library is restricted in
 | 
			
		||||
certain countries either by patents or by copyrighted interfaces, the
 | 
			
		||||
original copyright holder who places the Library under this License may add
 | 
			
		||||
an explicit geographical distribution limitation excluding those countries,
 | 
			
		||||
so that distribution is permitted only in or among countries not thus
 | 
			
		||||
excluded.  In such case, this License incorporates the limitation as if
 | 
			
		||||
written in the body of this License.
 | 
			
		||||
 | 
			
		||||
  13. The Free Software Foundation may publish revised and/or new
 | 
			
		||||
versions of the Library General Public License from time to time.
 | 
			
		||||
Such new versions will be similar in spirit to the present version,
 | 
			
		||||
but may differ in detail to address new problems or concerns.
 | 
			
		||||
 | 
			
		||||
Each version is given a distinguishing version number.  If the Library
 | 
			
		||||
specifies a version number of this License which applies to it and
 | 
			
		||||
"any later version", you have the option of following the terms and
 | 
			
		||||
conditions either of that version or of any later version published by
 | 
			
		||||
the Free Software Foundation.  If the Library does not specify a
 | 
			
		||||
license version number, you may choose any version ever published by
 | 
			
		||||
the Free Software Foundation.
 | 
			
		||||
 | 
			
		||||
  14. If you wish to incorporate parts of the Library into other free
 | 
			
		||||
programs whose distribution conditions are incompatible with these,
 | 
			
		||||
write to the author to ask for permission.  For software which is
 | 
			
		||||
copyrighted by the Free Software Foundation, write to the Free
 | 
			
		||||
Software Foundation; we sometimes make exceptions for this.  Our
 | 
			
		||||
decision will be guided by the two goals of preserving the free status
 | 
			
		||||
of all derivatives of our free software and of promoting the sharing
 | 
			
		||||
and reuse of software generally.
 | 
			
		||||
 | 
			
		||||
                            NO WARRANTY
 | 
			
		||||
 | 
			
		||||
  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
 | 
			
		||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
 | 
			
		||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
 | 
			
		||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
 | 
			
		||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 | 
			
		||||
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
 | 
			
		||||
LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
 | 
			
		||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
 | 
			
		||||
 | 
			
		||||
  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
 | 
			
		||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
 | 
			
		||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
 | 
			
		||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
 | 
			
		||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
 | 
			
		||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
 | 
			
		||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
 | 
			
		||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
 | 
			
		||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 | 
			
		||||
DAMAGES.
 | 
			
		||||
 | 
			
		||||
                     END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
           How to Apply These Terms to Your New Libraries
 | 
			
		||||
 | 
			
		||||
  If you develop a new library, and you want it to be of the greatest
 | 
			
		||||
possible use to the public, we recommend making it free software that
 | 
			
		||||
everyone can redistribute and change.  You can do so by permitting
 | 
			
		||||
redistribution under these terms (or, alternatively, under the terms of the
 | 
			
		||||
ordinary General Public License).
 | 
			
		||||
 | 
			
		||||
  To apply these terms, attach the following notices to the library.  It is
 | 
			
		||||
safest to attach them to the start of each source file to most effectively
 | 
			
		||||
convey the exclusion of warranty; and each file should have at least the
 | 
			
		||||
"copyright" line and a pointer to where the full notice is found.
 | 
			
		||||
 | 
			
		||||
    <one line to give the library's name and a brief idea of what it does.>
 | 
			
		||||
    Copyright (C) <year>  <name of author>
 | 
			
		||||
 | 
			
		||||
    This library is free software; you can redistribute it and/or
 | 
			
		||||
    modify it under the terms of the GNU Library General Public
 | 
			
		||||
    License as published by the Free Software Foundation; either
 | 
			
		||||
    version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
    This library is distributed in the hope that it will be useful,
 | 
			
		||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
    Library General Public License for more details.
 | 
			
		||||
 | 
			
		||||
    You should have received a copy of the GNU Library General Public
 | 
			
		||||
    License along with this library; if not, write to the Free Software
 | 
			
		||||
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
 | 
			
		||||
Also add information on how to contact you by electronic and paper mail.
 | 
			
		||||
 | 
			
		||||
You should also get your employer (if you work as a programmer) or your
 | 
			
		||||
school, if any, to sign a "copyright disclaimer" for the library, if
 | 
			
		||||
necessary.  Here is a sample; alter the names:
 | 
			
		||||
 | 
			
		||||
  Yoyodyne, Inc., hereby disclaims all copyright interest in the
 | 
			
		||||
  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
 | 
			
		||||
 | 
			
		||||
  <signature of Ty Coon>, 1 April 1990
 | 
			
		||||
  Ty Coon, President of Vice
 | 
			
		||||
 | 
			
		||||
That's all there is to it!
 | 
			
		||||
@@ -1,481 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 *   SPDX-FileCopyrightText: 2001-2010 Klaralvdalens Datakonsult AB.
 | 
			
		||||
 *   SPDX-License-Identifier: LGPL-2.0-only
 | 
			
		||||
 *
 | 
			
		||||
 *   The KD Tools Library is Copyright (C) 2001-2010 Klaralvdalens Datakonsult AB.
 | 
			
		||||
 */
 | 
			
		||||
#include "kdlockedsharedmemorypointer.h"
 | 
			
		||||
 | 
			
		||||
#if QT_VERSION >= 0x040400 || defined( DOXYGEN_RUN )
 | 
			
		||||
#ifndef QT_NO_SHAREDMEMORY
 | 
			
		||||
 | 
			
		||||
namespace kdtools
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
using namespace kdtools;
 | 
			
		||||
 | 
			
		||||
KDLockedSharedMemoryPointerBase::KDLockedSharedMemoryPointerBase( QSharedMemory * m )
 | 
			
		||||
    : locker( m ),
 | 
			
		||||
      mem( m )
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
KDLockedSharedMemoryPointerBase::KDLockedSharedMemoryPointerBase( QSharedMemory & m )
 | 
			
		||||
    : locker( &m ),
 | 
			
		||||
      mem( &m )
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
KDLockedSharedMemoryPointerBase::~KDLockedSharedMemoryPointerBase() {}
 | 
			
		||||
 | 
			
		||||
void * KDLockedSharedMemoryPointerBase::get() {
 | 
			
		||||
    return mem ? mem->data() : 0 ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const void * KDLockedSharedMemoryPointerBase::get() const {
 | 
			
		||||
    return mem ? mem->data() : 0 ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t KDLockedSharedMemoryPointerBase::byteSize() const {
 | 
			
		||||
    return mem ? mem->size() : 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \class KDLockedSharedMemoryPointer
 | 
			
		||||
  \ingroup core raii smartptr
 | 
			
		||||
  \brief Locking pointer for Qt shared memory segments
 | 
			
		||||
  \since_c 2.1
 | 
			
		||||
 | 
			
		||||
  (The exception safety of this class has not been evaluated yet.)
 | 
			
		||||
 | 
			
		||||
  KDLockedSharedMemoryPointer is a smart immutable pointer, which gives convenient and safe access to a QSharedMemory data segment.
 | 
			
		||||
  The content of a KDLockedSharedMemoryPointer cannot be changed during it's lifetime.
 | 
			
		||||
 | 
			
		||||
  You can use this class like a normal pointer to the shared memory segment and be sure it's locked while accessing it.
 | 
			
		||||
  \note You can only put simple types/structs/classes into it. structs and classes shall not contain any other pointers. See the
 | 
			
		||||
  documentation of QSharedMemory for details.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn KDLockedSharedMemoryPointer::KDLockedSharedMemoryPointer( QSharedMemory * mem )
 | 
			
		||||
 | 
			
		||||
  Constructor. Constructs a KDLockedSharedMemory pointer which points to the data segment of \a mem.
 | 
			
		||||
  The constructor locks \a mem. If the memory segment is already locked by another process, this constructor
 | 
			
		||||
  blocks until the lock is released.
 | 
			
		||||
 | 
			
		||||
  \post data() == mem->data() and the memory segment has been locked
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn KDLockedSharedMemoryPointer::KDLockedSharedMemoryPointer( QSharedMemory & mem )
 | 
			
		||||
 | 
			
		||||
  \overload
 | 
			
		||||
 | 
			
		||||
  \post data() == mem.data() and the memory segment has been locked
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn KDLockedSharedMemoryPointer::~KDLockedSharedMemoryPointer()
 | 
			
		||||
 | 
			
		||||
  Destructor. Unlocks the shared memory segment.
 | 
			
		||||
 | 
			
		||||
  \post The shared memory segment has been unlocked
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn T * KDLockedSharedMemoryPointer::get()
 | 
			
		||||
 | 
			
		||||
  \returns a pointer to the contained object.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn const T * KDLockedSharedMemoryPointer::get() const
 | 
			
		||||
 | 
			
		||||
  \returns a const pointer to the contained object
 | 
			
		||||
  \overload
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn T * KDLockedSharedMemoryPointer::data()
 | 
			
		||||
 | 
			
		||||
  Equivalent to get(), provided for consistency with Qt naming conventions.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn const T * KDLockedSharedMemoryPointer::data() const
 | 
			
		||||
 | 
			
		||||
  \overload
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn T & KDLockedSharedMemoryPointer::operator*()
 | 
			
		||||
 | 
			
		||||
  Dereference operator. Returns \link get() *get()\endlink.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn const T & KDLockedSharedMemoryPointer::operator*() const
 | 
			
		||||
 | 
			
		||||
  Dereference operator. Returns \link get() *get()\endlink.
 | 
			
		||||
  \overload
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn T * KDLockedSharedMemoryPointer::operator->()
 | 
			
		||||
 | 
			
		||||
  Member-by-pointer operator. Returns get().
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn const T * KDLockedSharedMemoryPointer::operator->() const
 | 
			
		||||
 | 
			
		||||
  Member-by-pointer operator. Returns get().
 | 
			
		||||
  \overload
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \class KDLockedSharedMemoryArray
 | 
			
		||||
  \ingroup core raii smartptr
 | 
			
		||||
  \brief Locking array pointer to Qt shared memory segments
 | 
			
		||||
  \since_c 2.1
 | 
			
		||||
 | 
			
		||||
  (The exception safety of this class has not been evaluated yet.)
 | 
			
		||||
 | 
			
		||||
  KDLockedSharedMemoryArray is a smart immutable pointer, which gives convenient and safe access to array data stored in a QSharedMemory
 | 
			
		||||
  data segment.
 | 
			
		||||
  The content of a KDLockedSharedMemoryArray cannot be changed during it's lifetime.
 | 
			
		||||
 | 
			
		||||
  You can use this class like a normal pointer to the shared memory segment and be sure it's locked while accessing it.
 | 
			
		||||
  \note You can only put arrays of simple types/structs/classes into it. structs and classes shall not contain any other pointers. See the
 | 
			
		||||
  documentation of QSharedMemory for details.
 | 
			
		||||
 | 
			
		||||
  \sa KDLockedSharedMemoryPointer
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn KDLockedSharedMemoryArray::KDLockedSharedMemoryArray( QSharedMemory* mem )
 | 
			
		||||
  Constructor. Constructs a KDLockedSharedMemoryArray which points to the data segment of \a mem. The constructor locks \a mem. If the memory
 | 
			
		||||
  segment is already locked by another process, this constructor blocks until the lock is release.
 | 
			
		||||
 | 
			
		||||
  \post get() == mem->data() and the memory segment has been locked
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn KDLockedSharedMemoryArray::KDLockedSharedMemoryArray( QSharedMemory& mem )
 | 
			
		||||
  \overload
 | 
			
		||||
 | 
			
		||||
  \post get() == mem->data() and the memory segment has been locked
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \typedef KDLockedSharedMemoryArray::size_type
 | 
			
		||||
  Typedef for std::size_t. Provided for STL compatibility.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \typedef KDLockedSharedMemoryArray::difference_type
 | 
			
		||||
  Typedef for std::ptrdiff_t. Provided for STL compatibility.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \typedef KDLockedSharedMemoryArray::iterator
 | 
			
		||||
  Typedef for T*. Provided for STL compatibility.
 | 
			
		||||
  \since_t 2.2
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \typedef KDLockedSharedMemoryArray::const_iterator
 | 
			
		||||
  Typedef for const T*. Provided for STL compatibility.
 | 
			
		||||
  \since_t 2.2
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \typedef KDLockedSharedMemoryArray::reverse_iterator
 | 
			
		||||
  Typedef for std::reverse_iterator< \link KDLockedSharedMemoryArray::iterator iterator\endlink >. Provided for STL compatibility.
 | 
			
		||||
  \since_t 2.2
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \typedef KDLockedSharedMemoryArray::const_reverse_iterator
 | 
			
		||||
  Typedef for std::reverse_iterator< \link KDLockedSharedMemoryArray::const_iterator const_iterator\endlink >. Provided for STL compatibility.
 | 
			
		||||
  \since_t 2.2
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn KDLockedSharedMemoryArray::iterator KDLockedSharedMemoryArray::begin()
 | 
			
		||||
  Returns an \link KDLockedSharedMemoryArray::iterator iterator\endlink pointing to the first item of the array.
 | 
			
		||||
  \since_f 2.2
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn KDLockedSharedMemoryArray::const_iterator KDLockedSharedMemoryArray::begin() const
 | 
			
		||||
  \overload
 | 
			
		||||
  \since_f 2.2
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn KDLockedSharedMemoryArray::iterator KDLockedSharedMemoryArray::end()
 | 
			
		||||
  Returns an \link KDLockedSharedMemoryArray::iterator iterator\endlink pointing to the item after the last item of the array.
 | 
			
		||||
  \since_f 2.2
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn KDLockedSharedMemoryArray::const_iterator KDLockedSharedMemoryArray::end() const
 | 
			
		||||
  \overload
 | 
			
		||||
  \since_f 2.2
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn KDLockedSharedMemoryArray::reverse_iterator KDLockedSharedMemoryArray::rbegin()
 | 
			
		||||
  Returns an \link KDLockedSharedMemoryArray::reverse_iterator reverse_iterator\endlink pointing to the item after the last item of the array.
 | 
			
		||||
  \since_f 2.2
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn KDLockedSharedMemoryArray::const_reverse_iterator KDLockedSharedMemoryArray::rbegin() const
 | 
			
		||||
  \overload
 | 
			
		||||
  \since_f 2.2
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn KDLockedSharedMemoryArray::reverse_iterator KDLockedSharedMemoryArray::rend()
 | 
			
		||||
  Returns an \link KDLockedSharedMemoryArray::reverse_iterator reverse_iterator\endlink pointing to the first item of the array.
 | 
			
		||||
  \since_f 2.2
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn KDLockedSharedMemoryArray::const_reverse_iterator KDLockedSharedMemoryArray::rend() const
 | 
			
		||||
  \overload
 | 
			
		||||
  \since_f 2.2
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn KDLockedSharedMemoryArray::size_type KDLockedSharedMemoryArray::size() const
 | 
			
		||||
  Returns the size of this array. The size is calculated from the storage size of T and
 | 
			
		||||
  the size of the shared memory segment.
 | 
			
		||||
  \since_f 2.2
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn T& KDLockedSharedMemoryArray::operator[]( difference_type n )
 | 
			
		||||
  Array access operator. Returns a reference to the item at index position \a n.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn const T& KDLockedSharedMemoryArray::operator[]( difference_type n ) const
 | 
			
		||||
  \overload
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
 \fn T& KDLockedSharedMemoryArray::front()
 | 
			
		||||
 Returns a reference to the first item in the array. This is the same as operator[](0).
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
 \fn const T& KDLockedSharedMemoryArray::front() const
 | 
			
		||||
 \overload
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
 \fn T& KDLockedSharedMemoryArray::back()
 | 
			
		||||
 Returns a reference to the last item in the array. This is the same as operator[](size()-1).
 | 
			
		||||
 \since_f 2.2
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
 \fn const T& KDLockedSharedMemoryArray::back() const
 | 
			
		||||
 \overload
 | 
			
		||||
 \since_f 2.2
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef eKDTOOLSCORE_UNITTESTS
 | 
			
		||||
 | 
			
		||||
#include <KDUnitTest/Test>
 | 
			
		||||
 | 
			
		||||
#include <QThread>
 | 
			
		||||
#include <QUuid>
 | 
			
		||||
 | 
			
		||||
namespace
 | 
			
		||||
{
 | 
			
		||||
    struct TestStruct
 | 
			
		||||
    {
 | 
			
		||||
        TestStruct( uint nn = 0 )
 | 
			
		||||
            : n( nn ),
 | 
			
		||||
              f( 0.0 ),
 | 
			
		||||
              c( '\0' ),
 | 
			
		||||
              b( false )
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
        uint n;
 | 
			
		||||
        double f;
 | 
			
		||||
        char c;
 | 
			
		||||
        bool b;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    bool operator==( const TestStruct& lhs, const TestStruct& rhs )
 | 
			
		||||
    {
 | 
			
		||||
        return lhs.n == rhs.n && lhs.f == rhs.f && lhs.c == rhs.c && lhs.b == rhs.b;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class TestThread : public QThread
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        TestThread( const QString& key )
 | 
			
		||||
            : mem( key )
 | 
			
		||||
        {
 | 
			
		||||
            mem.attach();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void run()
 | 
			
		||||
        {
 | 
			
		||||
            while( true )
 | 
			
		||||
            {
 | 
			
		||||
                msleep( 100 );
 | 
			
		||||
                kdtools::KDLockedSharedMemoryPointer< TestStruct > p( &mem );
 | 
			
		||||
                if( !p->b )
 | 
			
		||||
                    continue;
 | 
			
		||||
 | 
			
		||||
                p->n = 5;
 | 
			
		||||
                p->f = 3.14;
 | 
			
		||||
                p->c = 'A';
 | 
			
		||||
                p->b = false;
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        QSharedMemory mem;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    bool isConst( TestStruct* )
 | 
			
		||||
    {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool isConst( const TestStruct* )
 | 
			
		||||
    {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
KDAB_UNITTEST_SIMPLE( KDLockedSharedMemoryPointer, "kdcoretools" ) {
 | 
			
		||||
 | 
			
		||||
    const QString key = QUuid::createUuid();
 | 
			
		||||
    QSharedMemory mem( key );
 | 
			
		||||
    const bool created = mem.create( sizeof( TestStruct ) );
 | 
			
		||||
    assertTrue( created );
 | 
			
		||||
    if ( !created )
 | 
			
		||||
        return; // don't execute tests if shm coulnd't be created
 | 
			
		||||
 | 
			
		||||
    // On Windows, shared mem is only available in increments of page
 | 
			
		||||
    // size (4k), so don't fail if the segment is larger:
 | 
			
		||||
    const unsigned long mem_size = mem.size();
 | 
			
		||||
    assertGreaterOrEqual( mem_size, sizeof( TestStruct ) );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        kdtools::KDLockedSharedMemoryPointer< TestStruct > p( &mem );
 | 
			
		||||
        assertTrue( p );
 | 
			
		||||
        *p = TestStruct();
 | 
			
		||||
        assertEqual( p->n, 0u );
 | 
			
		||||
        assertEqual( p->f, 0.0 );
 | 
			
		||||
        assertEqual( p->c, '\0' );
 | 
			
		||||
        assertFalse( p->b );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        TestThread thread( key );
 | 
			
		||||
        assertEqual( thread.mem.key().toStdString(), key.toStdString() );
 | 
			
		||||
        assertEqual( static_cast< unsigned long >( thread.mem.size() ), mem_size );
 | 
			
		||||
        thread.start();
 | 
			
		||||
 | 
			
		||||
        assertTrue( thread.isRunning() );
 | 
			
		||||
        thread.wait( 2000 );
 | 
			
		||||
        assertTrue( thread.isRunning() );
 | 
			
		||||
 | 
			
		||||
        {
 | 
			
		||||
            kdtools::KDLockedSharedMemoryPointer< TestStruct > p( &mem );
 | 
			
		||||
            p->b = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        thread.wait( 2000 );
 | 
			
		||||
        assertFalse( thread.isRunning() );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        kdtools::KDLockedSharedMemoryPointer< TestStruct > p( &mem );
 | 
			
		||||
        assertEqual( p->n, 5u );
 | 
			
		||||
        assertEqual( p->f, 3.14 );
 | 
			
		||||
        assertEqual( p->c, 'A' );
 | 
			
		||||
        assertFalse( p->b );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        kdtools::KDLockedSharedMemoryPointer< TestStruct > p( mem );
 | 
			
		||||
        assertEqual( mem.data(), p.get() );
 | 
			
		||||
        assertEqual( p.get(), p.operator->() );
 | 
			
		||||
        assertEqual( p.get(), &(*p) );
 | 
			
		||||
        assertEqual( p.get(), p.data() );
 | 
			
		||||
        assertFalse( isConst( p.get() ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        const kdtools::KDLockedSharedMemoryPointer< TestStruct > p( &mem );
 | 
			
		||||
        assertEqual( mem.data(), p.get() );
 | 
			
		||||
        assertEqual( p.get(), p.operator->() );
 | 
			
		||||
        assertEqual( p.get(), &(*p) );
 | 
			
		||||
        assertEqual( p.get(), p.data() );
 | 
			
		||||
        assertTrue( isConst( p.get() ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        QSharedMemory mem2( key + key );
 | 
			
		||||
        const bool created2 = mem2.create( 16 * sizeof( TestStruct ) );
 | 
			
		||||
        assertTrue( created2 );
 | 
			
		||||
        if ( !created2 )
 | 
			
		||||
            return; // don't execute tests if shm coulnd't be created
 | 
			
		||||
 | 
			
		||||
        kdtools::KDLockedSharedMemoryArray<TestStruct> a( mem2 );
 | 
			
		||||
        assertTrue( a );
 | 
			
		||||
        assertEqual( a.get(), mem2.data() );
 | 
			
		||||
        assertEqual( &a[0], a.get() );
 | 
			
		||||
 | 
			
		||||
        a[1] = a[0];
 | 
			
		||||
        assertTrue( a[0] == a[1] );
 | 
			
		||||
 | 
			
		||||
        TestStruct ts;
 | 
			
		||||
        ts.n = 5;
 | 
			
		||||
        ts.f = 3.14;
 | 
			
		||||
        a[0] = ts;
 | 
			
		||||
        assertFalse( a[0] == a[1] );
 | 
			
		||||
        assertEqual( a.front().n, ts.n );
 | 
			
		||||
        assertEqual( a[0].f, ts.f );
 | 
			
		||||
        a[0].n = 10;
 | 
			
		||||
        assertEqual( a.front().n, 10u );
 | 
			
		||||
        ts = a[0];
 | 
			
		||||
        assertEqual( ts.n, 10u );
 | 
			
		||||
 | 
			
		||||
        std::vector< TestStruct > v;
 | 
			
		||||
        for( uint i = 0; i < a.size(); ++i )
 | 
			
		||||
            v.push_back( TestStruct( i ) );
 | 
			
		||||
 | 
			
		||||
        std::copy( v.begin(), v.end(), a.begin() );
 | 
			
		||||
        for( uint i = 0; i < a.size(); ++i )
 | 
			
		||||
            assertEqual( a[ i ].n, i );
 | 
			
		||||
        assertEqual( a.front().n, 0u );
 | 
			
		||||
        assertEqual( a.back().n, a.size() - 1 );
 | 
			
		||||
 | 
			
		||||
        std::copy( v.begin(), v.end(), a.rbegin() );
 | 
			
		||||
        for( uint i = 0; i < a.size(); ++i )
 | 
			
		||||
            assertEqual( a[ i ].n, a.size() - 1 - i );
 | 
			
		||||
        assertEqual( a.front().n, a.size() - 1 );
 | 
			
		||||
        assertEqual( a.back().n, 0u );
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
#endif // KDTOOLSCORE_UNITTESTS
 | 
			
		||||
#endif // QT_NO_SHAREDMEMORY
 | 
			
		||||
#endif // QT_VERSION >= 0x040400 || defined( DOXYGEN_RUN )
 | 
			
		||||
@@ -1,121 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 *   SPDX-FileCopyrightText: 2001-2010 Klaralvdalens Datakonsult AB.
 | 
			
		||||
 *   SPDX-License-Identifier: LGPL-2.0-only
 | 
			
		||||
 *
 | 
			
		||||
 *   The KD Tools Library is Copyright (C) 2001-2010 Klaralvdalens Datakonsult AB.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef __KDTOOLS__CORE__KDLOCKEDSHAREDMEMORYPOINTER_H__
 | 
			
		||||
#define __KDTOOLS__CORE__KDLOCKEDSHAREDMEMORYPOINTER_H__
 | 
			
		||||
 | 
			
		||||
#include <QtCore/QtGlobal>
 | 
			
		||||
 | 
			
		||||
#if QT_VERSION >= 0x040400 || defined( DOXYGEN_RUN )
 | 
			
		||||
#ifndef QT_NO_SHAREDMEMORY
 | 
			
		||||
 | 
			
		||||
#include "kdsharedmemorylocker.h"
 | 
			
		||||
#include <QtCore/QSharedMemory>
 | 
			
		||||
 | 
			
		||||
#include <cassert>
 | 
			
		||||
 | 
			
		||||
#ifndef DOXYGEN_RUN
 | 
			
		||||
namespace kdtools {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
class KDLockedSharedMemoryPointerBase {
 | 
			
		||||
protected:
 | 
			
		||||
    explicit KDLockedSharedMemoryPointerBase( QSharedMemory * mem );
 | 
			
		||||
    explicit KDLockedSharedMemoryPointerBase( QSharedMemory & mem );
 | 
			
		||||
    ~KDLockedSharedMemoryPointerBase();
 | 
			
		||||
 | 
			
		||||
    // PENDING(marc) do we really want const propagation here? I
 | 
			
		||||
    // usually declare all my RAII objects const...
 | 
			
		||||
    void * get();
 | 
			
		||||
    const void * get() const;
 | 
			
		||||
 | 
			
		||||
    KDAB_IMPLEMENT_SAFE_BOOL_OPERATOR( get() )
 | 
			
		||||
 | 
			
		||||
    size_t byteSize() const;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    KDSharedMemoryLocker locker;
 | 
			
		||||
    QSharedMemory * const mem;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template< typename T>
 | 
			
		||||
class MAKEINCLUDES_EXPORT KDLockedSharedMemoryPointer : KDLockedSharedMemoryPointerBase {
 | 
			
		||||
    KDAB_DISABLE_COPY( KDLockedSharedMemoryPointer );
 | 
			
		||||
public:
 | 
			
		||||
    explicit KDLockedSharedMemoryPointer( QSharedMemory * m )
 | 
			
		||||
        : KDLockedSharedMemoryPointerBase( m ) {}
 | 
			
		||||
    explicit KDLockedSharedMemoryPointer( QSharedMemory & m )
 | 
			
		||||
        : KDLockedSharedMemoryPointerBase( m ) {}
 | 
			
		||||
 | 
			
		||||
    T * get() { return static_cast<T*>( KDLockedSharedMemoryPointerBase::get() ); }
 | 
			
		||||
    const T * get() const { return static_cast<const T*>( KDLockedSharedMemoryPointerBase::get() ); }
 | 
			
		||||
 | 
			
		||||
    T * data() { return static_cast<T*>( get() ); }
 | 
			
		||||
    const T * data() const { return static_cast<const T*>( get() ); }
 | 
			
		||||
 | 
			
		||||
    T & operator*() { assert( get() ); return *get(); }
 | 
			
		||||
    const T & operator*() const { assert( get() ); return *get(); }
 | 
			
		||||
 | 
			
		||||
    T * operator->() { return get(); }
 | 
			
		||||
    const T * operator->() const { return get(); }
 | 
			
		||||
 | 
			
		||||
    KDAB_USING_SAFE_BOOL_OPERATOR( KDLockedSharedMemoryPointerBase )
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
class MAKEINCLUDES_EXPORT KDLockedSharedMemoryArray : KDLockedSharedMemoryPointerBase {
 | 
			
		||||
    KDAB_DISABLE_COPY( KDLockedSharedMemoryArray );
 | 
			
		||||
public:
 | 
			
		||||
    explicit KDLockedSharedMemoryArray( QSharedMemory * m )
 | 
			
		||||
        : KDLockedSharedMemoryPointerBase( m ) {}
 | 
			
		||||
    explicit KDLockedSharedMemoryArray( QSharedMemory & m )
 | 
			
		||||
        : KDLockedSharedMemoryPointerBase( m ) {}
 | 
			
		||||
 | 
			
		||||
    typedef std::size_t size_type;
 | 
			
		||||
    typedef std::ptrdiff_t difference_type;
 | 
			
		||||
    typedef T* iterator;
 | 
			
		||||
    typedef const T* const_iterator;
 | 
			
		||||
    typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
 | 
			
		||||
    typedef std::reverse_iterator< iterator > reverse_iterator;
 | 
			
		||||
 | 
			
		||||
    iterator begin() { return get(); }
 | 
			
		||||
    const_iterator begin() const { return get(); }
 | 
			
		||||
 | 
			
		||||
    iterator end() { return begin() + size(); }
 | 
			
		||||
    const_iterator end() const { return begin() + size(); }
 | 
			
		||||
 | 
			
		||||
    reverse_iterator rbegin() { return reverse_iterator( end() ); }
 | 
			
		||||
    const_reverse_iterator rbegin() const { return reverse_iterator( end() ); }
 | 
			
		||||
 | 
			
		||||
    reverse_iterator rend() { return reverse_iterator( begin() ); }
 | 
			
		||||
    const_reverse_iterator rend() const { return const_reverse_iterator( begin() ); }
 | 
			
		||||
 | 
			
		||||
    size_type size() const { return byteSize() / sizeof( T ); }
 | 
			
		||||
 | 
			
		||||
    T * get() { return static_cast<T*>( KDLockedSharedMemoryPointerBase::get() ); }
 | 
			
		||||
    const T * get() const { return static_cast<const T*>( KDLockedSharedMemoryPointerBase::get() ); }
 | 
			
		||||
 | 
			
		||||
    T & operator[]( difference_type n ) { assert( get() ); return *(get()+n); }
 | 
			
		||||
    const T & operator[]( difference_type n ) const { assert( get() ); return *(get()+n); }
 | 
			
		||||
 | 
			
		||||
    T & front() { assert( get() ); return *get(); }
 | 
			
		||||
    const T & front() const { assert( get() ); return *get(); }
 | 
			
		||||
 | 
			
		||||
    T & back() { assert( get() ); return *( get() + size() - 1 ); }
 | 
			
		||||
    const T & back() const { assert( get() ); return *( get() + size() - 1 ); }
 | 
			
		||||
 | 
			
		||||
    KDAB_USING_SAFE_BOOL_OPERATOR( KDLockedSharedMemoryPointerBase )
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#ifndef DOXYGEN_RUN
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* QT_NO_SHAREDMEMORY */
 | 
			
		||||
 | 
			
		||||
#endif /* QT_VERSION >= 0x040400 || defined( DOXYGEN_RUN ) */
 | 
			
		||||
 | 
			
		||||
#endif /* __KDTOOLS__CORE__KDLOCKEDSHAREDMEMORYPOINTER_H__ */
 | 
			
		||||
@@ -1,46 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 *   SPDX-FileCopyrightText: 2001-2010 Klaralvdalens Datakonsult AB.
 | 
			
		||||
 *   SPDX-License-Identifier: LGPL-2.0-only
 | 
			
		||||
 *
 | 
			
		||||
 *   The KD Tools Library is Copyright (C) 2001-2010 Klaralvdalens Datakonsult AB.
 | 
			
		||||
 */
 | 
			
		||||
#include "kdsharedmemorylocker.h"
 | 
			
		||||
 | 
			
		||||
#if QT_VERSION >= 0x040400 || defined( DOXYGEN_RUN )
 | 
			
		||||
 | 
			
		||||
#include <QSharedMemory>
 | 
			
		||||
 | 
			
		||||
using namespace kdtools;
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \class KDSharedMemoryLocker
 | 
			
		||||
  \ingroup raii core
 | 
			
		||||
  \brief Exception-safe and convenient wrapper around QSharedMemory::lock()
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Constructor. Locks the shared memory segment \a mem.
 | 
			
		||||
 * If another process has locking the segment, this constructor blocks
 | 
			
		||||
 * until the lock is released. The memory segments needs to be properly created or attached.
 | 
			
		||||
 */
 | 
			
		||||
KDSharedMemoryLocker::KDSharedMemoryLocker( QSharedMemory* mem )
 | 
			
		||||
    : mem( mem )
 | 
			
		||||
{
 | 
			
		||||
    mem->lock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Destructor. Unlocks the shared memory segment associated with this
 | 
			
		||||
 * KDSharedMemoryLocker.
 | 
			
		||||
 */
 | 
			
		||||
KDSharedMemoryLocker::~KDSharedMemoryLocker()
 | 
			
		||||
{
 | 
			
		||||
    mem->unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef KDAB_EVAL
 | 
			
		||||
#include KDAB_EVAL
 | 
			
		||||
static const EvalDialogChecker evalChecker( "KD Tools", false );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,42 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 *   SPDX-FileCopyrightText: 2001-2010 Klaralvdalens Datakonsult AB.
 | 
			
		||||
 *   SPDX-License-Identifier: LGPL-2.0-only
 | 
			
		||||
 *
 | 
			
		||||
 *   The KD Tools Library is Copyright (C) 2001-2010 Klaralvdalens Datakonsult AB.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef __KDTOOLS__CORE__KDSHAREDMEMORYLOCKER_H
 | 
			
		||||
#define __KDTOOLS__CORE__KDSHAREDMEMORYLOCKER_H
 | 
			
		||||
 | 
			
		||||
#include "kdtoolsglobal.h"
 | 
			
		||||
 | 
			
		||||
#if QT_VERSION < 0x040400 && !defined( DOXYGEN_RUN )
 | 
			
		||||
#ifdef Q_CC_GNU
 | 
			
		||||
#warning "Can't use KDTools KDSharedMemoryLocker with Qt versions prior to 4.4"
 | 
			
		||||
#endif
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
class QSharedMemory;
 | 
			
		||||
 | 
			
		||||
#ifndef DOXYGEN_RUN
 | 
			
		||||
namespace kdtools
 | 
			
		||||
{
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
class KDTOOLSCORE_EXPORT KDSharedMemoryLocker
 | 
			
		||||
{
 | 
			
		||||
    Q_DISABLE_COPY( KDSharedMemoryLocker )
 | 
			
		||||
public:
 | 
			
		||||
    KDSharedMemoryLocker( QSharedMemory* mem );
 | 
			
		||||
    ~KDSharedMemoryLocker();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    QSharedMemory* const mem;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#ifndef DOXYGEN_RUN
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,147 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 *   SPDX-FileCopyrightText: 2001-2010 Klaralvdalens Datakonsult AB.
 | 
			
		||||
 *   SPDX-License-Identifier: LGPL-2.0-only
 | 
			
		||||
 *
 | 
			
		||||
 *   The KD Tools Library is Copyright (C) 2001-2010 Klaralvdalens Datakonsult AB.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef KDTOOLSCORE_KDSINGLEAPPLICATIONGUARD_H
 | 
			
		||||
#define KDTOOLSCORE_KDSINGLEAPPLICATIONGUARD_H
 | 
			
		||||
 | 
			
		||||
#include <QtCore/QObject>
 | 
			
		||||
 | 
			
		||||
#ifndef QT_NO_SHAREDMEMORY
 | 
			
		||||
 | 
			
		||||
#include <QtCore/QStringList>
 | 
			
		||||
#include <QtCore/QMetaType>
 | 
			
		||||
 | 
			
		||||
#include "pimpl_ptr.h"
 | 
			
		||||
#include "DllMacro.h"
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
 | 
			
		||||
template <typename T> class QVector;
 | 
			
		||||
class QCoreApplication;
 | 
			
		||||
 | 
			
		||||
class DLLEXPORT KDSingleApplicationGuard : public QObject
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
    Q_ENUMS( Policy )
 | 
			
		||||
    Q_PROPERTY( bool operational READ isOperational )
 | 
			
		||||
    Q_PROPERTY( bool exitRequested READ isExitRequested )
 | 
			
		||||
    Q_PROPERTY( bool primaryInstance READ isPrimaryInstance NOTIFY becamePrimaryInstance )
 | 
			
		||||
    Q_PROPERTY( Policy policy READ policy WRITE setPolicy NOTIFY policyChanged )
 | 
			
		||||
public:
 | 
			
		||||
    enum Policy
 | 
			
		||||
    {
 | 
			
		||||
        NoPolicy = 0,
 | 
			
		||||
        AutoKillOtherInstances = 1
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    explicit KDSingleApplicationGuard( QObject * parent=nullptr );
 | 
			
		||||
    explicit KDSingleApplicationGuard( Policy policy, QObject * parent=nullptr );
 | 
			
		||||
    explicit KDSingleApplicationGuard( const QStringList & arguments, QObject * parent=nullptr );
 | 
			
		||||
    explicit KDSingleApplicationGuard( const QStringList & arguments, Policy policy, QObject * parent=nullptr );
 | 
			
		||||
    ~KDSingleApplicationGuard() override;
 | 
			
		||||
 | 
			
		||||
    bool isOperational() const;
 | 
			
		||||
 | 
			
		||||
    bool isExitRequested() const;
 | 
			
		||||
 | 
			
		||||
    bool isPrimaryInstance() const;
 | 
			
		||||
 | 
			
		||||
    Policy policy() const;
 | 
			
		||||
    void setPolicy( Policy policy );
 | 
			
		||||
 | 
			
		||||
    class Instance;
 | 
			
		||||
 | 
			
		||||
    QVector<Instance> instances() const;
 | 
			
		||||
 | 
			
		||||
Q_SIGNALS:
 | 
			
		||||
    void instanceStarted( const KDSingleApplicationGuard::Instance & instance );
 | 
			
		||||
    void instanceExited( const KDSingleApplicationGuard::Instance & instance );
 | 
			
		||||
    void exitRequested();
 | 
			
		||||
    void raiseRequested();
 | 
			
		||||
    void becamePrimaryInstance();
 | 
			
		||||
    void becameSecondaryInstance();
 | 
			
		||||
    void policyChanged( KDSingleApplicationGuard::Policy policy );
 | 
			
		||||
 | 
			
		||||
public Q_SLOTS:
 | 
			
		||||
    void shutdownOtherInstances();
 | 
			
		||||
    void killOtherInstances();
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    /*! \reimp */ bool event( QEvent * event ) override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
#ifndef Q_WS_WIN
 | 
			
		||||
    static void SIGINT_handler( int );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    friend struct ProcessInfo;
 | 
			
		||||
 | 
			
		||||
    class Private;
 | 
			
		||||
    kdtools::pimpl_ptr< Private > d;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class DLLEXPORT KDSingleApplicationGuard::Instance {
 | 
			
		||||
    friend class ::KDSingleApplicationGuard;
 | 
			
		||||
    friend class ::KDSingleApplicationGuard::Private;
 | 
			
		||||
    Instance( const QStringList &, bool, qint64 );
 | 
			
		||||
public:
 | 
			
		||||
    Instance();
 | 
			
		||||
    Instance( const Instance & other );
 | 
			
		||||
    ~Instance();
 | 
			
		||||
 | 
			
		||||
    void swap( Instance & other ) {
 | 
			
		||||
        std::swap( d, other.d );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Instance & operator=( Instance other ) {
 | 
			
		||||
        swap( other );
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool isNull() const { return !d; }
 | 
			
		||||
    bool isValid() const;
 | 
			
		||||
 | 
			
		||||
    bool areArgumentsTruncated() const;
 | 
			
		||||
 | 
			
		||||
    const QStringList & arguments() const;
 | 
			
		||||
    qint64 pid() const;
 | 
			
		||||
 | 
			
		||||
    void shutdown();
 | 
			
		||||
    void kill();
 | 
			
		||||
    void raise();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    class Private;
 | 
			
		||||
    Private * d;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
namespace std {
 | 
			
		||||
    template <>
 | 
			
		||||
    inline void swap( KDSingleApplicationGuard::Instance & lhs,
 | 
			
		||||
                      KDSingleApplicationGuard::Instance & rhs )
 | 
			
		||||
    {
 | 
			
		||||
        lhs.swap( rhs );
 | 
			
		||||
    }
 | 
			
		||||
} // namespace std
 | 
			
		||||
 | 
			
		||||
QT_BEGIN_NAMESPACE
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
inline void qSwap( KDSingleApplicationGuard::Instance & lhs,
 | 
			
		||||
                   KDSingleApplicationGuard::Instance & rhs )
 | 
			
		||||
{
 | 
			
		||||
    lhs.swap( rhs );
 | 
			
		||||
}
 | 
			
		||||
Q_DECLARE_METATYPE( KDSingleApplicationGuard::Instance )
 | 
			
		||||
Q_DECLARE_TYPEINFO( KDSingleApplicationGuard::Instance, Q_MOVABLE_TYPE );
 | 
			
		||||
 | 
			
		||||
QT_END_NAMESPACE
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif // QT_NO_SHAREDMEMORY
 | 
			
		||||
 | 
			
		||||
#endif /* KDTOOLSCORE_KDSINGLEAPPLICATIONGUARD_H */
 | 
			
		||||
@@ -1,42 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 *   SPDX-FileCopyrightText: 2001-2010 Klaralvdalens Datakonsult AB.
 | 
			
		||||
 *   SPDX-License-Identifier: LGPL-2.0-only
 | 
			
		||||
 *
 | 
			
		||||
 *   The KD Tools Library is Copyright (C) 2001-2010 Klaralvdalens Datakonsult AB.
 | 
			
		||||
 */
 | 
			
		||||
#include "kdtoolsglobal.h"
 | 
			
		||||
 | 
			
		||||
#include <QByteArray>
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
    struct Version {
 | 
			
		||||
	unsigned char v[3];
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    static inline bool operator<( const Version & lhs, const Version & rhs ) {
 | 
			
		||||
	return std::lexicographical_compare( lhs.v, lhs.v + 3, rhs.v, rhs.v + 3 );
 | 
			
		||||
    }
 | 
			
		||||
    static inline bool operator==( const Version & lhs, const Version & rhs ) {
 | 
			
		||||
	return std::equal( lhs.v, lhs.v + 3, rhs.v );
 | 
			
		||||
    }
 | 
			
		||||
    KDTOOLS_MAKE_RELATION_OPERATORS( Version, static inline )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Version kdParseQtVersion( const char * const version ) {
 | 
			
		||||
    if ( !version || qstrlen( version ) < 5 || version[1] != '.' || version[3] != '.' || ( version[5] != 0 && version[5] != '.' && version[5] != '-' ) )
 | 
			
		||||
	return Version(); // parse error
 | 
			
		||||
    const Version result = { { static_cast< unsigned char >( version[0] - '0' ),
 | 
			
		||||
                               static_cast< unsigned char >( version[2] - '0' ),
 | 
			
		||||
                               static_cast< unsigned char >( version[4] - '0' ) } };
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool _kdCheckQtVersion_impl( unsigned int major, unsigned int minor, unsigned int patchlevel ) {
 | 
			
		||||
    static const Version actual = kdParseQtVersion( qVersion() ); // do this only once each run...
 | 
			
		||||
    const Version requested = { { static_cast< unsigned char >( major ),
 | 
			
		||||
                                  static_cast< unsigned char >( minor ),
 | 
			
		||||
                                  static_cast< unsigned char >( patchlevel ) } };
 | 
			
		||||
    return actual >= requested;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										120
									
								
								3rdparty/kdsingleapplicationguard/kdtoolsglobal.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										120
									
								
								3rdparty/kdsingleapplicationguard/kdtoolsglobal.h
									
									
									
									
										vendored
									
									
								
							@@ -1,120 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 *   SPDX-FileCopyrightText: 2001-2010 Klaralvdalens Datakonsult AB.
 | 
			
		||||
 *   SPDX-License-Identifier: LGPL-2.0-only
 | 
			
		||||
 *
 | 
			
		||||
 *   The KD Tools Library is Copyright (C) 2001-2010 Klaralvdalens Datakonsult AB.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef KDTOOLS_KDTOOLSGLOBAL_H
 | 
			
		||||
#define KDTOOLS_KDTOOLSGLOBAL_H
 | 
			
		||||
 | 
			
		||||
#include <QtCore/QtGlobal>
 | 
			
		||||
 | 
			
		||||
#define KDAB_DISABLE_COPY( x ) private: x( const x & ); x & operator=( const x & )
 | 
			
		||||
 | 
			
		||||
#ifdef KDTOOLS_SHARED
 | 
			
		||||
#  ifdef BUILD_SHARED_KDTOOLSCORE
 | 
			
		||||
#    define KDTOOLSCORE_EXPORT Q_DECL_EXPORT
 | 
			
		||||
#  else
 | 
			
		||||
#    define KDTOOLSCORE_EXPORT Q_DECL_IMPORT
 | 
			
		||||
#  endif
 | 
			
		||||
#  ifdef BUILD_SHARED_KDTOOLSGUI
 | 
			
		||||
#    define KDTOOLSGUI_EXPORT Q_DECL_EXPORT
 | 
			
		||||
#  else
 | 
			
		||||
#    define KDTOOLSGUI_EXPORT Q_DECL_IMPORT
 | 
			
		||||
#  endif
 | 
			
		||||
#  ifdef BUILD_SHARED_KDTOOLSXML
 | 
			
		||||
#    define KDTOOLSXML_EXPORT Q_DECL_EXPORT
 | 
			
		||||
#  else
 | 
			
		||||
#    define KDTOOLSXML_EXPORT Q_DECL_IMPORT
 | 
			
		||||
#  endif
 | 
			
		||||
#  ifdef BUILD_SHARED_KDUPDATER
 | 
			
		||||
#    define KDTOOLS_UPDATER_EXPORT    Q_DECL_EXPORT
 | 
			
		||||
#  else
 | 
			
		||||
#    define KDTOOLS_UPDATER_EXPORT    Q_DECL_IMPORT
 | 
			
		||||
#  endif
 | 
			
		||||
#else // KDTOOLS_SHARED
 | 
			
		||||
#  define KDTOOLSCORE_EXPORT
 | 
			
		||||
#  define KDTOOLSGUI_EXPORT
 | 
			
		||||
#  define KDTOOLSXML_EXPORT
 | 
			
		||||
#  define KDTOOLS_UPDATER_EXPORT
 | 
			
		||||
#endif // KDTOOLS_SHARED
 | 
			
		||||
 | 
			
		||||
#define MAKEINCLUDES_EXPORT
 | 
			
		||||
 | 
			
		||||
#define DOXYGEN_PROPERTY( x )
 | 
			
		||||
#ifdef DOXYGEN_RUN
 | 
			
		||||
# define KDAB_IMPLEMENT_SAFE_BOOL_OPERATOR( func ) operator unspecified_bool_type() const { return func; }
 | 
			
		||||
# define KDAB_USING_SAFE_BOOL_OPERATOR( Class ) operator unspecified_bool_type() const;
 | 
			
		||||
#else
 | 
			
		||||
# define KDAB_IMPLEMENT_SAFE_BOOL_OPERATOR( func )                      \
 | 
			
		||||
    private:                                                            \
 | 
			
		||||
        struct __safe_bool_dummy__ { void nonnull() {} };               \
 | 
			
		||||
    public:                                                             \
 | 
			
		||||
        typedef void ( __safe_bool_dummy__::*unspecified_bool_type )(); \
 | 
			
		||||
        operator unspecified_bool_type() const {                        \
 | 
			
		||||
            return ( func ) ? &__safe_bool_dummy__::nonnull : 0 ;       \
 | 
			
		||||
        }
 | 
			
		||||
#define KDAB_USING_SAFE_BOOL_OPERATOR( Class ) \
 | 
			
		||||
    using Class::operator Class::unspecified_bool_type;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define KDTOOLS_MAKE_RELATION_OPERATORS( Class, linkage )             \
 | 
			
		||||
    linkage bool operator>( const Class & lhs, const Class & rhs ) {  \
 | 
			
		||||
        return operator<( rhs, lhs );                                 \
 | 
			
		||||
    }                                                                 \
 | 
			
		||||
    linkage bool operator!=( const Class & lhs, const Class & rhs ) { \
 | 
			
		||||
        return !operator==( lhs, rhs );                               \
 | 
			
		||||
    }                                                                 \
 | 
			
		||||
    linkage bool operator<=( const Class & lhs, const Class & rhs ) { \
 | 
			
		||||
        return !operator>( lhs, rhs );                                \
 | 
			
		||||
    }                                                                 \
 | 
			
		||||
    linkage bool operator>=( const Class & lhs, const Class & rhs ) { \
 | 
			
		||||
        return !operator<( lhs, rhs );                                \
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
inline T & __kdtools__dereference_for_methodcall( T & o ) {
 | 
			
		||||
    return o;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
inline T & __kdtools__dereference_for_methodcall( T * o ) {
 | 
			
		||||
    return *o;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define KDAB_SET_OBJECT_NAME( x ) __kdtools__dereference_for_methodcall( x ).setObjectName( QLatin1String( #x ) )
 | 
			
		||||
 | 
			
		||||
KDTOOLSCORE_EXPORT bool _kdCheckQtVersion_impl( unsigned int major, unsigned int minor=0, unsigned int patchlevel=0 );
 | 
			
		||||
static inline bool kdCheckQtVersion( unsigned int major, unsigned int minor=0, unsigned int patchlevel=0 ) {
 | 
			
		||||
    return (major<<16|minor<<8|patchlevel) <= static_cast<unsigned int>(QT_VERSION)
 | 
			
		||||
	|| _kdCheckQtVersion_impl( major, minor, patchlevel );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define KDTOOLS_DECLARE_PRIVATE_BASE( Class )                        \
 | 
			
		||||
protected:                                                           \
 | 
			
		||||
    class Private;                                                   \
 | 
			
		||||
    Private * d_func() { return _d; }                                \
 | 
			
		||||
    const Private * d_func() const { return _d; }                    \
 | 
			
		||||
    Class( Private * _d_, bool b ) : _d( _d_ ) { init(b); }          \
 | 
			
		||||
private:                                                             \
 | 
			
		||||
    void init(bool);                                                 \
 | 
			
		||||
private:                                                             \
 | 
			
		||||
    Private * _d
 | 
			
		||||
 | 
			
		||||
#define KDTOOLS_DECLARE_PRIVATE_DERIVED( Class, Base )                  \
 | 
			
		||||
protected:                                                              \
 | 
			
		||||
    class Private;                                                      \
 | 
			
		||||
    Private * d_func() {                                                \
 | 
			
		||||
        return reinterpret_cast<Private*>( Base::d_func() );            \
 | 
			
		||||
    }                                                                   \
 | 
			
		||||
    const Private * d_func() const {                                    \
 | 
			
		||||
        return reinterpret_cast<const Private*>( Base::d_func() );      \
 | 
			
		||||
    }                                                                   \
 | 
			
		||||
    Class( Private * _d_, bool b )                                      \
 | 
			
		||||
        : Base( reinterpret_cast<Base::Private*>(_d_), b ) { init(b); } \
 | 
			
		||||
private:                                                                \
 | 
			
		||||
    void init(bool)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* KDTOOLS_KDTOOLSGLOBAL_H */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										209
									
								
								3rdparty/kdsingleapplicationguard/pimpl_ptr.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										209
									
								
								3rdparty/kdsingleapplicationguard/pimpl_ptr.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,209 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 *   SPDX-FileCopyrightText: 2001-2010 Klaralvdalens Datakonsult AB.
 | 
			
		||||
 *   SPDX-License-Identifier: LGPL-2.0-only
 | 
			
		||||
 *
 | 
			
		||||
 *   The KD Tools Library is Copyright (C) 2001-2010 Klaralvdalens Datakonsult AB.
 | 
			
		||||
 */
 | 
			
		||||
#include "pimpl_ptr.h"
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \class pimpl_ptr:
 | 
			
		||||
  \ingroup core smartptr
 | 
			
		||||
  \brief Owning pointer for private implementations
 | 
			
		||||
  \since_c 2.1
 | 
			
		||||
 | 
			
		||||
  (The exception safety of this class has not been evaluated yet.)
 | 
			
		||||
 | 
			
		||||
  pimpl_ptr is a smart immutable pointer, which owns the contained object. Unlike other smart pointers,
 | 
			
		||||
  it creates a standard constructed object when instanciated via the
 | 
			
		||||
  \link pimpl_ptr() standard constructor\endlink.
 | 
			
		||||
  Additionally, pimpl_ptr respects constness of the pointer object and returns \c const \c T* for
 | 
			
		||||
  a const pimpl_ptr object.
 | 
			
		||||
 | 
			
		||||
  The content of a pimpl_ptr cannot be changed during it's lifetime.
 | 
			
		||||
 | 
			
		||||
  \section general-use General Use
 | 
			
		||||
 | 
			
		||||
  The general use case of pimpl_ptr is the "Pimpl Idiom", i.e. hiding the private implementation of a class
 | 
			
		||||
  from the user's compiler which see \c MyClass as
 | 
			
		||||
 | 
			
		||||
  \code
 | 
			
		||||
  class MyClass
 | 
			
		||||
  {
 | 
			
		||||
  public:
 | 
			
		||||
      MyClass();
 | 
			
		||||
      ~MyClass();
 | 
			
		||||
 | 
			
		||||
      // public class API
 | 
			
		||||
      int value() const;
 | 
			
		||||
 | 
			
		||||
  private:
 | 
			
		||||
      class Private; // defined later
 | 
			
		||||
      kdtools::pimpl_ptr< Private > d;
 | 
			
		||||
  };
 | 
			
		||||
  \endcode
 | 
			
		||||
 | 
			
		||||
  but not the private parts of it. These can only be seen (and accessed) by the code knowing \c MyClass::Private:
 | 
			
		||||
 | 
			
		||||
  \code
 | 
			
		||||
  class MyClass::Private
 | 
			
		||||
  {
 | 
			
		||||
  public:
 | 
			
		||||
      int value;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  MyClass::MyClass()
 | 
			
		||||
  {
 | 
			
		||||
      // d was automatically filled with new Private
 | 
			
		||||
      d->value = 42;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  MyClass::~MyClass()
 | 
			
		||||
  {
 | 
			
		||||
      // the content of d gets deleted automatically
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  int MyClass::value() const
 | 
			
		||||
  {
 | 
			
		||||
      // access the private part:
 | 
			
		||||
      // since MyClass::value() is const, the returned pointee is const, too
 | 
			
		||||
      return d->value;
 | 
			
		||||
  }
 | 
			
		||||
  \endcode
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn pimpl_ptr::pimpl_ptr()
 | 
			
		||||
 | 
			
		||||
  Default constructor. Constructs a pimpl_tr that contains (owns) a standard constructed
 | 
			
		||||
  instance of \c T.
 | 
			
		||||
 | 
			
		||||
  \post \c *this owns a new object.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn pimpl_ptr::pimpl_ptr( T * t )
 | 
			
		||||
 | 
			
		||||
  Constructor. Constructs a pimpl_ptr that contains (owns) \a t.
 | 
			
		||||
 | 
			
		||||
  \post get() == obj
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn pimpl_ptr::~pimpl_ptr()
 | 
			
		||||
 | 
			
		||||
  Destructor.
 | 
			
		||||
 | 
			
		||||
  \post The object previously owned by \c *this has been deleted.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn const T * pimpl_ptr::get() const
 | 
			
		||||
 | 
			
		||||
  \returns a const pointer to the contained (owned) object.
 | 
			
		||||
  \overload
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn T * pimpl_ptr::get()
 | 
			
		||||
 | 
			
		||||
  \returns a pointer to the contained (owned) object.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn const T & pimpl_ptr::operator*() const
 | 
			
		||||
 | 
			
		||||
  Dereference operator. Returns \link get() *get()\endlink.
 | 
			
		||||
  \overload
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn T & pimpl_ptr::operator*()
 | 
			
		||||
 | 
			
		||||
  Dereference operator. Returns \link get() *get()\endlink.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn const T * pimpl_ptr::operator->() const
 | 
			
		||||
 | 
			
		||||
  Member-by-pointer operator. Returns get().
 | 
			
		||||
  \overload
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
  \fn T * pimpl_ptr::operator->()
 | 
			
		||||
 | 
			
		||||
  Member-by-pointer operator. Returns get().
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifdef KDTOOLSCORE_UNITTESTS
 | 
			
		||||
 | 
			
		||||
#include <kdunittest/test.h>
 | 
			
		||||
 | 
			
		||||
#include <QObject>
 | 
			
		||||
#include <QPointer>
 | 
			
		||||
 | 
			
		||||
namespace
 | 
			
		||||
{
 | 
			
		||||
    struct ConstTester
 | 
			
		||||
    {
 | 
			
		||||
        bool isConst()
 | 
			
		||||
        {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool isConst() const
 | 
			
		||||
        {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
KDAB_UNITTEST_SIMPLE( pimpl_ptr, "kdcoretools" ) {
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        kdtools::pimpl_ptr< QObject > p;
 | 
			
		||||
        assertNotNull( p.get() );
 | 
			
		||||
        assertNull( p->parent() );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        QPointer< QObject > o;
 | 
			
		||||
        {
 | 
			
		||||
            kdtools::pimpl_ptr< QObject > qobject( new QObject );
 | 
			
		||||
            o = qobject.get();
 | 
			
		||||
            assertEqual( o, qobject.operator->() );
 | 
			
		||||
            assertEqual( o, &(qobject.operator*()) );
 | 
			
		||||
        }
 | 
			
		||||
        assertNull( o );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        const kdtools::pimpl_ptr< QObject > qobject( new QObject );
 | 
			
		||||
        const QObject* o = qobject.get();
 | 
			
		||||
        assertEqual( o, qobject.operator->() );
 | 
			
		||||
        assertEqual( o, &(qobject.operator*()) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        kdtools::pimpl_ptr< QObject > o1;
 | 
			
		||||
        assertTrue( o1 );
 | 
			
		||||
        kdtools::pimpl_ptr< QObject > o2( 0 );
 | 
			
		||||
        assertFalse( o2 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        const kdtools::pimpl_ptr< ConstTester > o1;
 | 
			
		||||
        kdtools::pimpl_ptr< ConstTester > o2;
 | 
			
		||||
        assertTrue( o1->isConst() );
 | 
			
		||||
        assertFalse( o2->isConst() );
 | 
			
		||||
        assertTrue( (*o1).isConst() );
 | 
			
		||||
        assertFalse( (*o2).isConst() );
 | 
			
		||||
        assertTrue( o1.get()->isConst() );
 | 
			
		||||
        assertFalse( o2.get()->isConst() );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // KDTOOLSCORE_UNITTESTS
 | 
			
		||||
							
								
								
									
										50
									
								
								3rdparty/kdsingleapplicationguard/pimpl_ptr.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										50
									
								
								3rdparty/kdsingleapplicationguard/pimpl_ptr.h
									
									
									
									
										vendored
									
									
								
							@@ -1,50 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 *   SPDX-FileCopyrightText: 2001-2010 Klaralvdalens Datakonsult AB.
 | 
			
		||||
 *   SPDX-License-Identifier: LGPL-2.0-only
 | 
			
		||||
 *
 | 
			
		||||
 *   The KD Tools Library is Copyright (C) 2001-2010 Klaralvdalens Datakonsult AB.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef KDTOOLSCORE_PIMPL_PTR_H
 | 
			
		||||
#define KDTOOLSCORE_PIMPL_PTR_H
 | 
			
		||||
 | 
			
		||||
#include "kdtoolsglobal.h"
 | 
			
		||||
 | 
			
		||||
#ifndef DOXYGEN_RUN
 | 
			
		||||
namespace kdtools {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    class pimpl_ptr {
 | 
			
		||||
        KDAB_DISABLE_COPY( pimpl_ptr );
 | 
			
		||||
        T * d;
 | 
			
		||||
    public:
 | 
			
		||||
        pimpl_ptr() : d( new T ) {}
 | 
			
		||||
        explicit pimpl_ptr( T * t ) : d( t ) {}
 | 
			
		||||
        ~pimpl_ptr() { delete d; d = nullptr; }
 | 
			
		||||
 | 
			
		||||
        T * get() { return d; }
 | 
			
		||||
        const T * get() const { return d; }
 | 
			
		||||
 | 
			
		||||
        T * operator->() { return get(); }
 | 
			
		||||
        const T * operator->() const { return get(); }
 | 
			
		||||
 | 
			
		||||
        T & operator*() { return *get(); }
 | 
			
		||||
        const T & operator*() const { return *get(); }
 | 
			
		||||
 | 
			
		||||
        KDAB_IMPLEMENT_SAFE_BOOL_OPERATOR( get() )
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // these are not implemented, so's we can catch their use at
 | 
			
		||||
    // link-time. Leaving them undeclared would open up a comparison
 | 
			
		||||
    // via operator unspecified-bool-type().
 | 
			
		||||
    template <typename T, typename S>
 | 
			
		||||
    void operator==( const pimpl_ptr<T> &, const pimpl_ptr<S> & );
 | 
			
		||||
    template <typename T, typename S>
 | 
			
		||||
    void operator!=( const pimpl_ptr<T> &, const pimpl_ptr<S> & );
 | 
			
		||||
 | 
			
		||||
#ifndef DOXYGEN_RUN
 | 
			
		||||
} // namespace kdtools
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* KDTOOLSCORE_PIMPL_PTR_H */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										16
									
								
								3rdparty/pybind11/CMakeLists.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								3rdparty/pybind11/CMakeLists.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
# === This file is part of Calamares - <https://calamares.io> ===
 | 
			
		||||
#
 | 
			
		||||
#   SPDX-FileCopyrightText: 2023 Adriaan de Groot <groot@kde.org>
 | 
			
		||||
#   SPDX-License-Identifier: BSD-2-Clause
 | 
			
		||||
#
 | 
			
		||||
###
 | 
			
		||||
#
 | 
			
		||||
# This is a very-stripped-down way of getting the bundled pybind11
 | 
			
		||||
 | 
			
		||||
add_library(pybind11_headers INTERFACE)
 | 
			
		||||
add_library(pybind11::headers ALIAS pybind11_headers)
 | 
			
		||||
 | 
			
		||||
target_include_directories(pybind11_headers INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include)
 | 
			
		||||
target_link_libraries(pybind11_headers INTERFACE Python::Python) # Was searched-for at top-level
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										29
									
								
								3rdparty/pybind11/LICENSE
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								3rdparty/pybind11/LICENSE
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>, All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 | 
			
		||||
1. Redistributions of source code must retain the above copyright notice, this
 | 
			
		||||
   list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
2. Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
   this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
   and/or other materials provided with the distribution.
 | 
			
		||||
 | 
			
		||||
3. Neither the name of the copyright holder nor the names of its contributors
 | 
			
		||||
   may be used to endorse or promote products derived from this software
 | 
			
		||||
   without specific prior written permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 | 
			
		||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 | 
			
		||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 | 
			
		||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 | 
			
		||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 | 
			
		||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 | 
			
		||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
Please also refer to the file .github/CONTRIBUTING.md, which clarifies licensing of
 | 
			
		||||
external contributions to this project including patches, pull requests, etc.
 | 
			
		||||
							
								
								
									
										6
									
								
								3rdparty/pybind11/MANIFEST.in
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								3rdparty/pybind11/MANIFEST.in
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
prune tests
 | 
			
		||||
recursive-include pybind11/include/pybind11 *.h
 | 
			
		||||
recursive-include pybind11 *.py
 | 
			
		||||
recursive-include pybind11 py.typed
 | 
			
		||||
include pybind11/share/cmake/pybind11/*.cmake
 | 
			
		||||
include LICENSE README.rst SECURITY.md pyproject.toml setup.py setup.cfg
 | 
			
		||||
							
								
								
									
										180
									
								
								3rdparty/pybind11/README.rst
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										180
									
								
								3rdparty/pybind11/README.rst
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,180 @@
 | 
			
		||||
.. figure:: https://github.com/pybind/pybind11/raw/master/docs/pybind11-logo.png
 | 
			
		||||
   :alt: pybind11 logo
 | 
			
		||||
 | 
			
		||||
**pybind11 — Seamless operability between C++11 and Python**
 | 
			
		||||
 | 
			
		||||
|Latest Documentation Status| |Stable Documentation Status| |Gitter chat| |GitHub Discussions| |CI| |Build status|
 | 
			
		||||
 | 
			
		||||
|Repology| |PyPI package| |Conda-forge| |Python Versions|
 | 
			
		||||
 | 
			
		||||
`Setuptools example <https://github.com/pybind/python_example>`_
 | 
			
		||||
• `Scikit-build example <https://github.com/pybind/scikit_build_example>`_
 | 
			
		||||
• `CMake example <https://github.com/pybind/cmake_example>`_
 | 
			
		||||
 | 
			
		||||
.. start
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
**pybind11** is a lightweight header-only library that exposes C++ types
 | 
			
		||||
in Python and vice versa, mainly to create Python bindings of existing
 | 
			
		||||
C++ code. Its goals and syntax are similar to the excellent
 | 
			
		||||
`Boost.Python <http://www.boost.org/doc/libs/1_58_0/libs/python/doc/>`_
 | 
			
		||||
library by David Abrahams: to minimize boilerplate code in traditional
 | 
			
		||||
extension modules by inferring type information using compile-time
 | 
			
		||||
introspection.
 | 
			
		||||
 | 
			
		||||
The main issue with Boost.Python—and the reason for creating such a
 | 
			
		||||
similar project—is Boost. Boost is an enormously large and complex suite
 | 
			
		||||
of utility libraries that works with almost every C++ compiler in
 | 
			
		||||
existence. This compatibility has its cost: arcane template tricks and
 | 
			
		||||
workarounds are necessary to support the oldest and buggiest of compiler
 | 
			
		||||
specimens. Now that C++11-compatible compilers are widely available,
 | 
			
		||||
this heavy machinery has become an excessively large and unnecessary
 | 
			
		||||
dependency.
 | 
			
		||||
 | 
			
		||||
Think of this library as a tiny self-contained version of Boost.Python
 | 
			
		||||
with everything stripped away that isn't relevant for binding
 | 
			
		||||
generation. Without comments, the core header files only require ~4K
 | 
			
		||||
lines of code and depend on Python (3.6+, or PyPy) and the C++
 | 
			
		||||
standard library. This compact implementation was possible thanks to
 | 
			
		||||
some of the new C++11 language features (specifically: tuples, lambda
 | 
			
		||||
functions and variadic templates). Since its creation, this library has
 | 
			
		||||
grown beyond Boost.Python in many ways, leading to dramatically simpler
 | 
			
		||||
binding code in many common situations.
 | 
			
		||||
 | 
			
		||||
Tutorial and reference documentation is provided at
 | 
			
		||||
`pybind11.readthedocs.io <https://pybind11.readthedocs.io/en/latest>`_.
 | 
			
		||||
A PDF version of the manual is available
 | 
			
		||||
`here <https://pybind11.readthedocs.io/_/downloads/en/latest/pdf/>`_.
 | 
			
		||||
And the source code is always available at
 | 
			
		||||
`github.com/pybind/pybind11 <https://github.com/pybind/pybind11>`_.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Core features
 | 
			
		||||
-------------
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
pybind11 can map the following core C++ features to Python:
 | 
			
		||||
 | 
			
		||||
- Functions accepting and returning custom data structures per value,
 | 
			
		||||
  reference, or pointer
 | 
			
		||||
- Instance methods and static methods
 | 
			
		||||
- Overloaded functions
 | 
			
		||||
- Instance attributes and static attributes
 | 
			
		||||
- Arbitrary exception types
 | 
			
		||||
- Enumerations
 | 
			
		||||
- Callbacks
 | 
			
		||||
- Iterators and ranges
 | 
			
		||||
- Custom operators
 | 
			
		||||
- Single and multiple inheritance
 | 
			
		||||
- STL data structures
 | 
			
		||||
- Smart pointers with reference counting like ``std::shared_ptr``
 | 
			
		||||
- Internal references with correct reference counting
 | 
			
		||||
- C++ classes with virtual (and pure virtual) methods can be extended
 | 
			
		||||
  in Python
 | 
			
		||||
 | 
			
		||||
Goodies
 | 
			
		||||
-------
 | 
			
		||||
 | 
			
		||||
In addition to the core functionality, pybind11 provides some extra
 | 
			
		||||
goodies:
 | 
			
		||||
 | 
			
		||||
- Python 3.6+, and PyPy3 7.3 are supported with an implementation-agnostic
 | 
			
		||||
  interface (pybind11 2.9 was the last version to support Python 2 and 3.5).
 | 
			
		||||
 | 
			
		||||
- It is possible to bind C++11 lambda functions with captured
 | 
			
		||||
  variables. The lambda capture data is stored inside the resulting
 | 
			
		||||
  Python function object.
 | 
			
		||||
 | 
			
		||||
- pybind11 uses C++11 move constructors and move assignment operators
 | 
			
		||||
  whenever possible to efficiently transfer custom data types.
 | 
			
		||||
 | 
			
		||||
- It's easy to expose the internal storage of custom data types through
 | 
			
		||||
  Pythons' buffer protocols. This is handy e.g. for fast conversion
 | 
			
		||||
  between C++ matrix classes like Eigen and NumPy without expensive
 | 
			
		||||
  copy operations.
 | 
			
		||||
 | 
			
		||||
- pybind11 can automatically vectorize functions so that they are
 | 
			
		||||
  transparently applied to all entries of one or more NumPy array
 | 
			
		||||
  arguments.
 | 
			
		||||
 | 
			
		||||
- Python's slice-based access and assignment operations can be
 | 
			
		||||
  supported with just a few lines of code.
 | 
			
		||||
 | 
			
		||||
- Everything is contained in just a few header files; there is no need
 | 
			
		||||
  to link against any additional libraries.
 | 
			
		||||
 | 
			
		||||
- Binaries are generally smaller by a factor of at least 2 compared to
 | 
			
		||||
  equivalent bindings generated by Boost.Python. A recent pybind11
 | 
			
		||||
  conversion of PyRosetta, an enormous Boost.Python binding project,
 | 
			
		||||
  `reported <https://graylab.jhu.edu/Sergey/2016.RosettaCon/PyRosetta-4.pdf>`_
 | 
			
		||||
  a binary size reduction of **5.4x** and compile time reduction by
 | 
			
		||||
  **5.8x**.
 | 
			
		||||
 | 
			
		||||
- Function signatures are precomputed at compile time (using
 | 
			
		||||
  ``constexpr``), leading to smaller binaries.
 | 
			
		||||
 | 
			
		||||
- With little extra effort, C++ types can be pickled and unpickled
 | 
			
		||||
  similar to regular Python objects.
 | 
			
		||||
 | 
			
		||||
Supported compilers
 | 
			
		||||
-------------------
 | 
			
		||||
 | 
			
		||||
1. Clang/LLVM 3.3 or newer (for Apple Xcode's clang, this is 5.0.0 or
 | 
			
		||||
   newer)
 | 
			
		||||
2. GCC 4.8 or newer
 | 
			
		||||
3. Microsoft Visual Studio 2017 or newer
 | 
			
		||||
4. Intel classic C++ compiler 18 or newer (ICC 20.2 tested in CI)
 | 
			
		||||
5. Cygwin/GCC (previously tested on 2.5.1)
 | 
			
		||||
6. NVCC (CUDA 11.0 tested in CI)
 | 
			
		||||
7. NVIDIA PGI (20.9 tested in CI)
 | 
			
		||||
 | 
			
		||||
About
 | 
			
		||||
-----
 | 
			
		||||
 | 
			
		||||
This project was created by `Wenzel
 | 
			
		||||
Jakob <http://rgl.epfl.ch/people/wjakob>`_. Significant features and/or
 | 
			
		||||
improvements to the code were contributed by Jonas Adler, Lori A. Burns,
 | 
			
		||||
Sylvain Corlay, Eric Cousineau, Aaron Gokaslan, Ralf Grosse-Kunstleve, Trent Houliston, Axel
 | 
			
		||||
Huebl, @hulucc, Yannick Jadoul, Sergey Lyskov, Johan Mabille, Tomasz Miąsko,
 | 
			
		||||
Dean Moldovan, Ben Pritchard, Jason Rhinelander, Boris Schäling, Pim
 | 
			
		||||
Schellart, Henry Schreiner, Ivan Smirnov, Boris Staletic, and Patrick Stewart.
 | 
			
		||||
 | 
			
		||||
We thank Google for a generous financial contribution to the continuous
 | 
			
		||||
integration infrastructure used by this project.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Contributing
 | 
			
		||||
~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
See the `contributing
 | 
			
		||||
guide <https://github.com/pybind/pybind11/blob/master/.github/CONTRIBUTING.md>`_
 | 
			
		||||
for information on building and contributing to pybind11.
 | 
			
		||||
 | 
			
		||||
License
 | 
			
		||||
~~~~~~~
 | 
			
		||||
 | 
			
		||||
pybind11 is provided under a BSD-style license that can be found in the
 | 
			
		||||
`LICENSE <https://github.com/pybind/pybind11/blob/master/LICENSE>`_
 | 
			
		||||
file. By using, distributing, or contributing to this project, you agree
 | 
			
		||||
to the terms and conditions of this license.
 | 
			
		||||
 | 
			
		||||
.. |Latest Documentation Status| image:: https://readthedocs.org/projects/pybind11/badge?version=latest
 | 
			
		||||
   :target: http://pybind11.readthedocs.org/en/latest
 | 
			
		||||
.. |Stable Documentation Status| image:: https://img.shields.io/badge/docs-stable-blue.svg
 | 
			
		||||
   :target: http://pybind11.readthedocs.org/en/stable
 | 
			
		||||
.. |Gitter chat| image:: https://img.shields.io/gitter/room/gitterHQ/gitter.svg
 | 
			
		||||
   :target: https://gitter.im/pybind/Lobby
 | 
			
		||||
.. |CI| image:: https://github.com/pybind/pybind11/workflows/CI/badge.svg
 | 
			
		||||
   :target: https://github.com/pybind/pybind11/actions
 | 
			
		||||
.. |Build status| image:: https://ci.appveyor.com/api/projects/status/riaj54pn4h08xy40?svg=true
 | 
			
		||||
   :target: https://ci.appveyor.com/project/wjakob/pybind11
 | 
			
		||||
.. |PyPI package| image:: https://img.shields.io/pypi/v/pybind11.svg
 | 
			
		||||
   :target: https://pypi.org/project/pybind11/
 | 
			
		||||
.. |Conda-forge| image:: https://img.shields.io/conda/vn/conda-forge/pybind11.svg
 | 
			
		||||
   :target: https://github.com/conda-forge/pybind11-feedstock
 | 
			
		||||
.. |Repology| image:: https://repology.org/badge/latest-versions/python:pybind11.svg
 | 
			
		||||
   :target: https://repology.org/project/python:pybind11/versions
 | 
			
		||||
.. |Python Versions| image:: https://img.shields.io/pypi/pyversions/pybind11.svg
 | 
			
		||||
   :target: https://pypi.org/project/pybind11/
 | 
			
		||||
.. |GitHub Discussions| image:: https://img.shields.io/static/v1?label=Discussions&message=Ask&color=blue&logo=github
 | 
			
		||||
   :target: https://github.com/pybind/pybind11/discussions
 | 
			
		||||
							
								
								
									
										13
									
								
								3rdparty/pybind11/SECURITY.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								3rdparty/pybind11/SECURITY.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
# Security Policy
 | 
			
		||||
 | 
			
		||||
## Supported Versions
 | 
			
		||||
 | 
			
		||||
Security updates are applied only to the latest release.
 | 
			
		||||
 | 
			
		||||
## Reporting a Vulnerability
 | 
			
		||||
 | 
			
		||||
If you have discovered a security vulnerability in this project, please report it privately. **Do not disclose it as a public issue.** This gives us time to work with you to fix the issue before public exposure, reducing the chance that the exploit will be used before a patch is released.
 | 
			
		||||
 | 
			
		||||
Please disclose it at [security advisory](https://github.com/pybind/pybind11/security/advisories/new).
 | 
			
		||||
 | 
			
		||||
This project is maintained by a team of volunteers on a reasonable-effort basis. As such, please give us at least 90 days to work on a fix before public exposure.
 | 
			
		||||
							
								
								
									
										690
									
								
								3rdparty/pybind11/include/pybind11/attr.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										690
									
								
								3rdparty/pybind11/include/pybind11/attr.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,690 @@
 | 
			
		||||
/*
 | 
			
		||||
    pybind11/attr.h: Infrastructure for processing custom
 | 
			
		||||
    type and function attributes
 | 
			
		||||
 | 
			
		||||
    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
 | 
			
		||||
 | 
			
		||||
    All rights reserved. Use of this source code is governed by a
 | 
			
		||||
    BSD-style license that can be found in the LICENSE file.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "detail/common.h"
 | 
			
		||||
#include "cast.h"
 | 
			
		||||
 | 
			
		||||
#include <functional>
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
 | 
			
		||||
 | 
			
		||||
/// \addtogroup annotations
 | 
			
		||||
/// @{
 | 
			
		||||
 | 
			
		||||
/// Annotation for methods
 | 
			
		||||
struct is_method {
 | 
			
		||||
    handle class_;
 | 
			
		||||
    explicit is_method(const handle &c) : class_(c) {}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Annotation for setters
 | 
			
		||||
struct is_setter {};
 | 
			
		||||
 | 
			
		||||
/// Annotation for operators
 | 
			
		||||
struct is_operator {};
 | 
			
		||||
 | 
			
		||||
/// Annotation for classes that cannot be subclassed
 | 
			
		||||
struct is_final {};
 | 
			
		||||
 | 
			
		||||
/// Annotation for parent scope
 | 
			
		||||
struct scope {
 | 
			
		||||
    handle value;
 | 
			
		||||
    explicit scope(const handle &s) : value(s) {}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Annotation for documentation
 | 
			
		||||
struct doc {
 | 
			
		||||
    const char *value;
 | 
			
		||||
    explicit doc(const char *value) : value(value) {}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Annotation for function names
 | 
			
		||||
struct name {
 | 
			
		||||
    const char *value;
 | 
			
		||||
    explicit name(const char *value) : value(value) {}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Annotation indicating that a function is an overload associated with a given "sibling"
 | 
			
		||||
struct sibling {
 | 
			
		||||
    handle value;
 | 
			
		||||
    explicit sibling(const handle &value) : value(value.ptr()) {}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Annotation indicating that a class derives from another given type
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct base {
 | 
			
		||||
 | 
			
		||||
    PYBIND11_DEPRECATED(
 | 
			
		||||
        "base<T>() was deprecated in favor of specifying 'T' as a template argument to class_")
 | 
			
		||||
    base() = default;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Keep patient alive while nurse lives
 | 
			
		||||
template <size_t Nurse, size_t Patient>
 | 
			
		||||
struct keep_alive {};
 | 
			
		||||
 | 
			
		||||
/// Annotation indicating that a class is involved in a multiple inheritance relationship
 | 
			
		||||
struct multiple_inheritance {};
 | 
			
		||||
 | 
			
		||||
/// Annotation which enables dynamic attributes, i.e. adds `__dict__` to a class
 | 
			
		||||
struct dynamic_attr {};
 | 
			
		||||
 | 
			
		||||
/// Annotation which enables the buffer protocol for a type
 | 
			
		||||
struct buffer_protocol {};
 | 
			
		||||
 | 
			
		||||
/// Annotation which requests that a special metaclass is created for a type
 | 
			
		||||
struct metaclass {
 | 
			
		||||
    handle value;
 | 
			
		||||
 | 
			
		||||
    PYBIND11_DEPRECATED("py::metaclass() is no longer required. It's turned on by default now.")
 | 
			
		||||
    metaclass() = default;
 | 
			
		||||
 | 
			
		||||
    /// Override pybind11's default metaclass
 | 
			
		||||
    explicit metaclass(handle value) : value(value) {}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Specifies a custom callback with signature `void (PyHeapTypeObject*)` that
 | 
			
		||||
/// may be used to customize the Python type.
 | 
			
		||||
///
 | 
			
		||||
/// The callback is invoked immediately before `PyType_Ready`.
 | 
			
		||||
///
 | 
			
		||||
/// Note: This is an advanced interface, and uses of it may require changes to
 | 
			
		||||
/// work with later versions of pybind11.  You may wish to consult the
 | 
			
		||||
/// implementation of `make_new_python_type` in `detail/classes.h` to understand
 | 
			
		||||
/// the context in which the callback will be run.
 | 
			
		||||
struct custom_type_setup {
 | 
			
		||||
    using callback = std::function<void(PyHeapTypeObject *heap_type)>;
 | 
			
		||||
 | 
			
		||||
    explicit custom_type_setup(callback value) : value(std::move(value)) {}
 | 
			
		||||
 | 
			
		||||
    callback value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Annotation that marks a class as local to the module:
 | 
			
		||||
struct module_local {
 | 
			
		||||
    const bool value;
 | 
			
		||||
    constexpr explicit module_local(bool v = true) : value(v) {}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Annotation to mark enums as an arithmetic type
 | 
			
		||||
struct arithmetic {};
 | 
			
		||||
 | 
			
		||||
/// Mark a function for addition at the beginning of the existing overload chain instead of the end
 | 
			
		||||
struct prepend {};
 | 
			
		||||
 | 
			
		||||
/** \rst
 | 
			
		||||
    A call policy which places one or more guard variables (``Ts...``) around the function call.
 | 
			
		||||
 | 
			
		||||
    For example, this definition:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: cpp
 | 
			
		||||
 | 
			
		||||
        m.def("foo", foo, py::call_guard<T>());
 | 
			
		||||
 | 
			
		||||
    is equivalent to the following pseudocode:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: cpp
 | 
			
		||||
 | 
			
		||||
        m.def("foo", [](args...) {
 | 
			
		||||
            T scope_guard;
 | 
			
		||||
            return foo(args...); // forwarded arguments
 | 
			
		||||
        });
 | 
			
		||||
 \endrst */
 | 
			
		||||
template <typename... Ts>
 | 
			
		||||
struct call_guard;
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct call_guard<> {
 | 
			
		||||
    using type = detail::void_type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct call_guard<T> {
 | 
			
		||||
    static_assert(std::is_default_constructible<T>::value,
 | 
			
		||||
                  "The guard type must be default constructible");
 | 
			
		||||
 | 
			
		||||
    using type = T;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T, typename... Ts>
 | 
			
		||||
struct call_guard<T, Ts...> {
 | 
			
		||||
    struct type {
 | 
			
		||||
        T guard{}; // Compose multiple guard types with left-to-right default-constructor order
 | 
			
		||||
        typename call_guard<Ts...>::type next{};
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// @} annotations
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(detail)
 | 
			
		||||
/* Forward declarations */
 | 
			
		||||
enum op_id : int;
 | 
			
		||||
enum op_type : int;
 | 
			
		||||
struct undefined_t;
 | 
			
		||||
template <op_id id, op_type ot, typename L = undefined_t, typename R = undefined_t>
 | 
			
		||||
struct op_;
 | 
			
		||||
void keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret);
 | 
			
		||||
 | 
			
		||||
/// Internal data structure which holds metadata about a keyword argument
 | 
			
		||||
struct argument_record {
 | 
			
		||||
    const char *name;  ///< Argument name
 | 
			
		||||
    const char *descr; ///< Human-readable version of the argument value
 | 
			
		||||
    handle value;      ///< Associated Python object
 | 
			
		||||
    bool convert : 1;  ///< True if the argument is allowed to convert when loading
 | 
			
		||||
    bool none : 1;     ///< True if None is allowed when loading
 | 
			
		||||
 | 
			
		||||
    argument_record(const char *name, const char *descr, handle value, bool convert, bool none)
 | 
			
		||||
        : name(name), descr(descr), value(value), convert(convert), none(none) {}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Internal data structure which holds metadata about a bound function (signature, overloads,
 | 
			
		||||
/// etc.)
 | 
			
		||||
struct function_record {
 | 
			
		||||
    function_record()
 | 
			
		||||
        : is_constructor(false), is_new_style_constructor(false), is_stateless(false),
 | 
			
		||||
          is_operator(false), is_method(false), is_setter(false), has_args(false),
 | 
			
		||||
          has_kwargs(false), prepend(false) {}
 | 
			
		||||
 | 
			
		||||
    /// Function name
 | 
			
		||||
    char *name = nullptr; /* why no C++ strings? They generate heavier code.. */
 | 
			
		||||
 | 
			
		||||
    // User-specified documentation string
 | 
			
		||||
    char *doc = nullptr;
 | 
			
		||||
 | 
			
		||||
    /// Human-readable version of the function signature
 | 
			
		||||
    char *signature = nullptr;
 | 
			
		||||
 | 
			
		||||
    /// List of registered keyword arguments
 | 
			
		||||
    std::vector<argument_record> args;
 | 
			
		||||
 | 
			
		||||
    /// Pointer to lambda function which converts arguments and performs the actual call
 | 
			
		||||
    handle (*impl)(function_call &) = nullptr;
 | 
			
		||||
 | 
			
		||||
    /// Storage for the wrapped function pointer and captured data, if any
 | 
			
		||||
    void *data[3] = {};
 | 
			
		||||
 | 
			
		||||
    /// Pointer to custom destructor for 'data' (if needed)
 | 
			
		||||
    void (*free_data)(function_record *ptr) = nullptr;
 | 
			
		||||
 | 
			
		||||
    /// Return value policy associated with this function
 | 
			
		||||
    return_value_policy policy = return_value_policy::automatic;
 | 
			
		||||
 | 
			
		||||
    /// True if name == '__init__'
 | 
			
		||||
    bool is_constructor : 1;
 | 
			
		||||
 | 
			
		||||
    /// True if this is a new-style `__init__` defined in `detail/init.h`
 | 
			
		||||
    bool is_new_style_constructor : 1;
 | 
			
		||||
 | 
			
		||||
    /// True if this is a stateless function pointer
 | 
			
		||||
    bool is_stateless : 1;
 | 
			
		||||
 | 
			
		||||
    /// True if this is an operator (__add__), etc.
 | 
			
		||||
    bool is_operator : 1;
 | 
			
		||||
 | 
			
		||||
    /// True if this is a method
 | 
			
		||||
    bool is_method : 1;
 | 
			
		||||
 | 
			
		||||
    /// True if this is a setter
 | 
			
		||||
    bool is_setter : 1;
 | 
			
		||||
 | 
			
		||||
    /// True if the function has a '*args' argument
 | 
			
		||||
    bool has_args : 1;
 | 
			
		||||
 | 
			
		||||
    /// True if the function has a '**kwargs' argument
 | 
			
		||||
    bool has_kwargs : 1;
 | 
			
		||||
 | 
			
		||||
    /// True if this function is to be inserted at the beginning of the overload resolution chain
 | 
			
		||||
    bool prepend : 1;
 | 
			
		||||
 | 
			
		||||
    /// Number of arguments (including py::args and/or py::kwargs, if present)
 | 
			
		||||
    std::uint16_t nargs;
 | 
			
		||||
 | 
			
		||||
    /// Number of leading positional arguments, which are terminated by a py::args or py::kwargs
 | 
			
		||||
    /// argument or by a py::kw_only annotation.
 | 
			
		||||
    std::uint16_t nargs_pos = 0;
 | 
			
		||||
 | 
			
		||||
    /// Number of leading arguments (counted in `nargs`) that are positional-only
 | 
			
		||||
    std::uint16_t nargs_pos_only = 0;
 | 
			
		||||
 | 
			
		||||
    /// Python method object
 | 
			
		||||
    PyMethodDef *def = nullptr;
 | 
			
		||||
 | 
			
		||||
    /// Python handle to the parent scope (a class or a module)
 | 
			
		||||
    handle scope;
 | 
			
		||||
 | 
			
		||||
    /// Python handle to the sibling function representing an overload chain
 | 
			
		||||
    handle sibling;
 | 
			
		||||
 | 
			
		||||
    /// Pointer to next overload
 | 
			
		||||
    function_record *next = nullptr;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Special data structure which (temporarily) holds metadata about a bound class
 | 
			
		||||
struct type_record {
 | 
			
		||||
    PYBIND11_NOINLINE type_record()
 | 
			
		||||
        : multiple_inheritance(false), dynamic_attr(false), buffer_protocol(false),
 | 
			
		||||
          default_holder(true), module_local(false), is_final(false) {}
 | 
			
		||||
 | 
			
		||||
    /// Handle to the parent scope
 | 
			
		||||
    handle scope;
 | 
			
		||||
 | 
			
		||||
    /// Name of the class
 | 
			
		||||
    const char *name = nullptr;
 | 
			
		||||
 | 
			
		||||
    // Pointer to RTTI type_info data structure
 | 
			
		||||
    const std::type_info *type = nullptr;
 | 
			
		||||
 | 
			
		||||
    /// How large is the underlying C++ type?
 | 
			
		||||
    size_t type_size = 0;
 | 
			
		||||
 | 
			
		||||
    /// What is the alignment of the underlying C++ type?
 | 
			
		||||
    size_t type_align = 0;
 | 
			
		||||
 | 
			
		||||
    /// How large is the type's holder?
 | 
			
		||||
    size_t holder_size = 0;
 | 
			
		||||
 | 
			
		||||
    /// The global operator new can be overridden with a class-specific variant
 | 
			
		||||
    void *(*operator_new)(size_t) = nullptr;
 | 
			
		||||
 | 
			
		||||
    /// Function pointer to class_<..>::init_instance
 | 
			
		||||
    void (*init_instance)(instance *, const void *) = nullptr;
 | 
			
		||||
 | 
			
		||||
    /// Function pointer to class_<..>::dealloc
 | 
			
		||||
    void (*dealloc)(detail::value_and_holder &) = nullptr;
 | 
			
		||||
 | 
			
		||||
    /// List of base classes of the newly created type
 | 
			
		||||
    list bases;
 | 
			
		||||
 | 
			
		||||
    /// Optional docstring
 | 
			
		||||
    const char *doc = nullptr;
 | 
			
		||||
 | 
			
		||||
    /// Custom metaclass (optional)
 | 
			
		||||
    handle metaclass;
 | 
			
		||||
 | 
			
		||||
    /// Custom type setup.
 | 
			
		||||
    custom_type_setup::callback custom_type_setup_callback;
 | 
			
		||||
 | 
			
		||||
    /// Multiple inheritance marker
 | 
			
		||||
    bool multiple_inheritance : 1;
 | 
			
		||||
 | 
			
		||||
    /// Does the class manage a __dict__?
 | 
			
		||||
    bool dynamic_attr : 1;
 | 
			
		||||
 | 
			
		||||
    /// Does the class implement the buffer protocol?
 | 
			
		||||
    bool buffer_protocol : 1;
 | 
			
		||||
 | 
			
		||||
    /// Is the default (unique_ptr) holder type used?
 | 
			
		||||
    bool default_holder : 1;
 | 
			
		||||
 | 
			
		||||
    /// Is the class definition local to the module shared object?
 | 
			
		||||
    bool module_local : 1;
 | 
			
		||||
 | 
			
		||||
    /// Is the class inheritable from python classes?
 | 
			
		||||
    bool is_final : 1;
 | 
			
		||||
 | 
			
		||||
    PYBIND11_NOINLINE void add_base(const std::type_info &base, void *(*caster)(void *) ) {
 | 
			
		||||
        auto *base_info = detail::get_type_info(base, false);
 | 
			
		||||
        if (!base_info) {
 | 
			
		||||
            std::string tname(base.name());
 | 
			
		||||
            detail::clean_type_id(tname);
 | 
			
		||||
            pybind11_fail("generic_type: type \"" + std::string(name)
 | 
			
		||||
                          + "\" referenced unknown base type \"" + tname + "\"");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (default_holder != base_info->default_holder) {
 | 
			
		||||
            std::string tname(base.name());
 | 
			
		||||
            detail::clean_type_id(tname);
 | 
			
		||||
            pybind11_fail("generic_type: type \"" + std::string(name) + "\" "
 | 
			
		||||
                          + (default_holder ? "does not have" : "has")
 | 
			
		||||
                          + " a non-default holder type while its base \"" + tname + "\" "
 | 
			
		||||
                          + (base_info->default_holder ? "does not" : "does"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bases.append((PyObject *) base_info->type);
 | 
			
		||||
 | 
			
		||||
#if PY_VERSION_HEX < 0x030B0000
 | 
			
		||||
        dynamic_attr |= base_info->type->tp_dictoffset != 0;
 | 
			
		||||
#else
 | 
			
		||||
        dynamic_attr |= (base_info->type->tp_flags & Py_TPFLAGS_MANAGED_DICT) != 0;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        if (caster) {
 | 
			
		||||
            base_info->implicit_casts.emplace_back(type, caster);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
inline function_call::function_call(const function_record &f, handle p) : func(f), parent(p) {
 | 
			
		||||
    args.reserve(f.nargs);
 | 
			
		||||
    args_convert.reserve(f.nargs);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Tag for a new-style `__init__` defined in `detail/init.h`
 | 
			
		||||
struct is_new_style_constructor {};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Partial template specializations to process custom attributes provided to
 | 
			
		||||
 * cpp_function_ and class_. These are either used to initialize the respective
 | 
			
		||||
 * fields in the type_record and function_record data structures or executed at
 | 
			
		||||
 * runtime to deal with custom call policies (e.g. keep_alive).
 | 
			
		||||
 */
 | 
			
		||||
template <typename T, typename SFINAE = void>
 | 
			
		||||
struct process_attribute;
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct process_attribute_default {
 | 
			
		||||
    /// Default implementation: do nothing
 | 
			
		||||
    static void init(const T &, function_record *) {}
 | 
			
		||||
    static void init(const T &, type_record *) {}
 | 
			
		||||
    static void precall(function_call &) {}
 | 
			
		||||
    static void postcall(function_call &, handle) {}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Process an attribute specifying the function's name
 | 
			
		||||
template <>
 | 
			
		||||
struct process_attribute<name> : process_attribute_default<name> {
 | 
			
		||||
    static void init(const name &n, function_record *r) { r->name = const_cast<char *>(n.value); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Process an attribute specifying the function's docstring
 | 
			
		||||
template <>
 | 
			
		||||
struct process_attribute<doc> : process_attribute_default<doc> {
 | 
			
		||||
    static void init(const doc &n, function_record *r) { r->doc = const_cast<char *>(n.value); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Process an attribute specifying the function's docstring (provided as a C-style string)
 | 
			
		||||
template <>
 | 
			
		||||
struct process_attribute<const char *> : process_attribute_default<const char *> {
 | 
			
		||||
    static void init(const char *d, function_record *r) { r->doc = const_cast<char *>(d); }
 | 
			
		||||
    static void init(const char *d, type_record *r) { r->doc = d; }
 | 
			
		||||
};
 | 
			
		||||
template <>
 | 
			
		||||
struct process_attribute<char *> : process_attribute<const char *> {};
 | 
			
		||||
 | 
			
		||||
/// Process an attribute indicating the function's return value policy
 | 
			
		||||
template <>
 | 
			
		||||
struct process_attribute<return_value_policy> : process_attribute_default<return_value_policy> {
 | 
			
		||||
    static void init(const return_value_policy &p, function_record *r) { r->policy = p; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Process an attribute which indicates that this is an overloaded function associated with a
 | 
			
		||||
/// given sibling
 | 
			
		||||
template <>
 | 
			
		||||
struct process_attribute<sibling> : process_attribute_default<sibling> {
 | 
			
		||||
    static void init(const sibling &s, function_record *r) { r->sibling = s.value; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Process an attribute which indicates that this function is a method
 | 
			
		||||
template <>
 | 
			
		||||
struct process_attribute<is_method> : process_attribute_default<is_method> {
 | 
			
		||||
    static void init(const is_method &s, function_record *r) {
 | 
			
		||||
        r->is_method = true;
 | 
			
		||||
        r->scope = s.class_;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Process an attribute which indicates that this function is a setter
 | 
			
		||||
template <>
 | 
			
		||||
struct process_attribute<is_setter> : process_attribute_default<is_setter> {
 | 
			
		||||
    static void init(const is_setter &, function_record *r) { r->is_setter = true; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Process an attribute which indicates the parent scope of a method
 | 
			
		||||
template <>
 | 
			
		||||
struct process_attribute<scope> : process_attribute_default<scope> {
 | 
			
		||||
    static void init(const scope &s, function_record *r) { r->scope = s.value; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Process an attribute which indicates that this function is an operator
 | 
			
		||||
template <>
 | 
			
		||||
struct process_attribute<is_operator> : process_attribute_default<is_operator> {
 | 
			
		||||
    static void init(const is_operator &, function_record *r) { r->is_operator = true; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct process_attribute<is_new_style_constructor>
 | 
			
		||||
    : process_attribute_default<is_new_style_constructor> {
 | 
			
		||||
    static void init(const is_new_style_constructor &, function_record *r) {
 | 
			
		||||
        r->is_new_style_constructor = true;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
inline void check_kw_only_arg(const arg &a, function_record *r) {
 | 
			
		||||
    if (r->args.size() > r->nargs_pos && (!a.name || a.name[0] == '\0')) {
 | 
			
		||||
        pybind11_fail("arg(): cannot specify an unnamed argument after a kw_only() annotation or "
 | 
			
		||||
                      "args() argument");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void append_self_arg_if_needed(function_record *r) {
 | 
			
		||||
    if (r->is_method && r->args.empty()) {
 | 
			
		||||
        r->args.emplace_back("self", nullptr, handle(), /*convert=*/true, /*none=*/false);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Process a keyword argument attribute (*without* a default value)
 | 
			
		||||
template <>
 | 
			
		||||
struct process_attribute<arg> : process_attribute_default<arg> {
 | 
			
		||||
    static void init(const arg &a, function_record *r) {
 | 
			
		||||
        append_self_arg_if_needed(r);
 | 
			
		||||
        r->args.emplace_back(a.name, nullptr, handle(), !a.flag_noconvert, a.flag_none);
 | 
			
		||||
 | 
			
		||||
        check_kw_only_arg(a, r);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Process a keyword argument attribute (*with* a default value)
 | 
			
		||||
template <>
 | 
			
		||||
struct process_attribute<arg_v> : process_attribute_default<arg_v> {
 | 
			
		||||
    static void init(const arg_v &a, function_record *r) {
 | 
			
		||||
        if (r->is_method && r->args.empty()) {
 | 
			
		||||
            r->args.emplace_back(
 | 
			
		||||
                "self", /*descr=*/nullptr, /*parent=*/handle(), /*convert=*/true, /*none=*/false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!a.value) {
 | 
			
		||||
#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
 | 
			
		||||
            std::string descr("'");
 | 
			
		||||
            if (a.name) {
 | 
			
		||||
                descr += std::string(a.name) + ": ";
 | 
			
		||||
            }
 | 
			
		||||
            descr += a.type + "'";
 | 
			
		||||
            if (r->is_method) {
 | 
			
		||||
                if (r->name) {
 | 
			
		||||
                    descr += " in method '" + (std::string) str(r->scope) + "."
 | 
			
		||||
                             + (std::string) r->name + "'";
 | 
			
		||||
                } else {
 | 
			
		||||
                    descr += " in method of '" + (std::string) str(r->scope) + "'";
 | 
			
		||||
                }
 | 
			
		||||
            } else if (r->name) {
 | 
			
		||||
                descr += " in function '" + (std::string) r->name + "'";
 | 
			
		||||
            }
 | 
			
		||||
            pybind11_fail("arg(): could not convert default argument " + descr
 | 
			
		||||
                          + " into a Python object (type not registered yet?)");
 | 
			
		||||
#else
 | 
			
		||||
            pybind11_fail("arg(): could not convert default argument "
 | 
			
		||||
                          "into a Python object (type not registered yet?). "
 | 
			
		||||
                          "#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for "
 | 
			
		||||
                          "more information.");
 | 
			
		||||
#endif
 | 
			
		||||
        }
 | 
			
		||||
        r->args.emplace_back(a.name, a.descr, a.value.inc_ref(), !a.flag_noconvert, a.flag_none);
 | 
			
		||||
 | 
			
		||||
        check_kw_only_arg(a, r);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Process a keyword-only-arguments-follow pseudo argument
 | 
			
		||||
template <>
 | 
			
		||||
struct process_attribute<kw_only> : process_attribute_default<kw_only> {
 | 
			
		||||
    static void init(const kw_only &, function_record *r) {
 | 
			
		||||
        append_self_arg_if_needed(r);
 | 
			
		||||
        if (r->has_args && r->nargs_pos != static_cast<std::uint16_t>(r->args.size())) {
 | 
			
		||||
            pybind11_fail("Mismatched args() and kw_only(): they must occur at the same relative "
 | 
			
		||||
                          "argument location (or omit kw_only() entirely)");
 | 
			
		||||
        }
 | 
			
		||||
        r->nargs_pos = static_cast<std::uint16_t>(r->args.size());
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Process a positional-only-argument maker
 | 
			
		||||
template <>
 | 
			
		||||
struct process_attribute<pos_only> : process_attribute_default<pos_only> {
 | 
			
		||||
    static void init(const pos_only &, function_record *r) {
 | 
			
		||||
        append_self_arg_if_needed(r);
 | 
			
		||||
        r->nargs_pos_only = static_cast<std::uint16_t>(r->args.size());
 | 
			
		||||
        if (r->nargs_pos_only > r->nargs_pos) {
 | 
			
		||||
            pybind11_fail("pos_only(): cannot follow a py::args() argument");
 | 
			
		||||
        }
 | 
			
		||||
        // It also can't follow a kw_only, but a static_assert in pybind11.h checks that
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Process a parent class attribute.  Single inheritance only (class_ itself already guarantees
 | 
			
		||||
/// that)
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct process_attribute<T, enable_if_t<is_pyobject<T>::value>>
 | 
			
		||||
    : process_attribute_default<handle> {
 | 
			
		||||
    static void init(const handle &h, type_record *r) { r->bases.append(h); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Process a parent class attribute (deprecated, does not support multiple inheritance)
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct process_attribute<base<T>> : process_attribute_default<base<T>> {
 | 
			
		||||
    static void init(const base<T> &, type_record *r) { r->add_base(typeid(T), nullptr); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Process a multiple inheritance attribute
 | 
			
		||||
template <>
 | 
			
		||||
struct process_attribute<multiple_inheritance> : process_attribute_default<multiple_inheritance> {
 | 
			
		||||
    static void init(const multiple_inheritance &, type_record *r) {
 | 
			
		||||
        r->multiple_inheritance = true;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct process_attribute<dynamic_attr> : process_attribute_default<dynamic_attr> {
 | 
			
		||||
    static void init(const dynamic_attr &, type_record *r) { r->dynamic_attr = true; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct process_attribute<custom_type_setup> {
 | 
			
		||||
    static void init(const custom_type_setup &value, type_record *r) {
 | 
			
		||||
        r->custom_type_setup_callback = value.value;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct process_attribute<is_final> : process_attribute_default<is_final> {
 | 
			
		||||
    static void init(const is_final &, type_record *r) { r->is_final = true; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct process_attribute<buffer_protocol> : process_attribute_default<buffer_protocol> {
 | 
			
		||||
    static void init(const buffer_protocol &, type_record *r) { r->buffer_protocol = true; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct process_attribute<metaclass> : process_attribute_default<metaclass> {
 | 
			
		||||
    static void init(const metaclass &m, type_record *r) { r->metaclass = m.value; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct process_attribute<module_local> : process_attribute_default<module_local> {
 | 
			
		||||
    static void init(const module_local &l, type_record *r) { r->module_local = l.value; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Process a 'prepend' attribute, putting this at the beginning of the overload chain
 | 
			
		||||
template <>
 | 
			
		||||
struct process_attribute<prepend> : process_attribute_default<prepend> {
 | 
			
		||||
    static void init(const prepend &, function_record *r) { r->prepend = true; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Process an 'arithmetic' attribute for enums (does nothing here)
 | 
			
		||||
template <>
 | 
			
		||||
struct process_attribute<arithmetic> : process_attribute_default<arithmetic> {};
 | 
			
		||||
 | 
			
		||||
template <typename... Ts>
 | 
			
		||||
struct process_attribute<call_guard<Ts...>> : process_attribute_default<call_guard<Ts...>> {};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Process a keep_alive call policy -- invokes keep_alive_impl during the
 | 
			
		||||
 * pre-call handler if both Nurse, Patient != 0 and use the post-call handler
 | 
			
		||||
 * otherwise
 | 
			
		||||
 */
 | 
			
		||||
template <size_t Nurse, size_t Patient>
 | 
			
		||||
struct process_attribute<keep_alive<Nurse, Patient>>
 | 
			
		||||
    : public process_attribute_default<keep_alive<Nurse, Patient>> {
 | 
			
		||||
    template <size_t N = Nurse, size_t P = Patient, enable_if_t<N != 0 && P != 0, int> = 0>
 | 
			
		||||
    static void precall(function_call &call) {
 | 
			
		||||
        keep_alive_impl(Nurse, Patient, call, handle());
 | 
			
		||||
    }
 | 
			
		||||
    template <size_t N = Nurse, size_t P = Patient, enable_if_t<N != 0 && P != 0, int> = 0>
 | 
			
		||||
    static void postcall(function_call &, handle) {}
 | 
			
		||||
    template <size_t N = Nurse, size_t P = Patient, enable_if_t<N == 0 || P == 0, int> = 0>
 | 
			
		||||
    static void precall(function_call &) {}
 | 
			
		||||
    template <size_t N = Nurse, size_t P = Patient, enable_if_t<N == 0 || P == 0, int> = 0>
 | 
			
		||||
    static void postcall(function_call &call, handle ret) {
 | 
			
		||||
        keep_alive_impl(Nurse, Patient, call, ret);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Recursively iterate over variadic template arguments
 | 
			
		||||
template <typename... Args>
 | 
			
		||||
struct process_attributes {
 | 
			
		||||
    static void init(const Args &...args, function_record *r) {
 | 
			
		||||
        PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(r);
 | 
			
		||||
        PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(r);
 | 
			
		||||
        using expander = int[];
 | 
			
		||||
        (void) expander{
 | 
			
		||||
            0, ((void) process_attribute<typename std::decay<Args>::type>::init(args, r), 0)...};
 | 
			
		||||
    }
 | 
			
		||||
    static void init(const Args &...args, type_record *r) {
 | 
			
		||||
        PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(r);
 | 
			
		||||
        PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(r);
 | 
			
		||||
        using expander = int[];
 | 
			
		||||
        (void) expander{0,
 | 
			
		||||
                        (process_attribute<typename std::decay<Args>::type>::init(args, r), 0)...};
 | 
			
		||||
    }
 | 
			
		||||
    static void precall(function_call &call) {
 | 
			
		||||
        PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(call);
 | 
			
		||||
        using expander = int[];
 | 
			
		||||
        (void) expander{0,
 | 
			
		||||
                        (process_attribute<typename std::decay<Args>::type>::precall(call), 0)...};
 | 
			
		||||
    }
 | 
			
		||||
    static void postcall(function_call &call, handle fn_ret) {
 | 
			
		||||
        PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(call, fn_ret);
 | 
			
		||||
        PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(fn_ret);
 | 
			
		||||
        using expander = int[];
 | 
			
		||||
        (void) expander{
 | 
			
		||||
            0, (process_attribute<typename std::decay<Args>::type>::postcall(call, fn_ret), 0)...};
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
using is_call_guard = is_instantiation<call_guard, T>;
 | 
			
		||||
 | 
			
		||||
/// Extract the ``type`` from the first `call_guard` in `Extras...` (or `void_type` if none found)
 | 
			
		||||
template <typename... Extra>
 | 
			
		||||
using extract_guard_t = typename exactly_one_t<is_call_guard, call_guard<>, Extra...>::type;
 | 
			
		||||
 | 
			
		||||
/// Check the number of named arguments at compile time
 | 
			
		||||
template <typename... Extra,
 | 
			
		||||
          size_t named = constexpr_sum(std::is_base_of<arg, Extra>::value...),
 | 
			
		||||
          size_t self = constexpr_sum(std::is_same<is_method, Extra>::value...)>
 | 
			
		||||
constexpr bool expected_num_args(size_t nargs, bool has_args, bool has_kwargs) {
 | 
			
		||||
    PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(nargs, has_args, has_kwargs);
 | 
			
		||||
    return named == 0 || (self + named + size_t(has_args) + size_t(has_kwargs)) == nargs;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_END(detail)
 | 
			
		||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
 | 
			
		||||
							
								
								
									
										208
									
								
								3rdparty/pybind11/include/pybind11/buffer_info.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										208
									
								
								3rdparty/pybind11/include/pybind11/buffer_info.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,208 @@
 | 
			
		||||
/*
 | 
			
		||||
    pybind11/buffer_info.h: Python buffer object interface
 | 
			
		||||
 | 
			
		||||
    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
 | 
			
		||||
 | 
			
		||||
    All rights reserved. Use of this source code is governed by a
 | 
			
		||||
    BSD-style license that can be found in the LICENSE file.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "detail/common.h"
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(detail)
 | 
			
		||||
 | 
			
		||||
// Default, C-style strides
 | 
			
		||||
inline std::vector<ssize_t> c_strides(const std::vector<ssize_t> &shape, ssize_t itemsize) {
 | 
			
		||||
    auto ndim = shape.size();
 | 
			
		||||
    std::vector<ssize_t> strides(ndim, itemsize);
 | 
			
		||||
    if (ndim > 0) {
 | 
			
		||||
        for (size_t i = ndim - 1; i > 0; --i) {
 | 
			
		||||
            strides[i - 1] = strides[i] * shape[i];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return strides;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// F-style strides; default when constructing an array_t with `ExtraFlags & f_style`
 | 
			
		||||
inline std::vector<ssize_t> f_strides(const std::vector<ssize_t> &shape, ssize_t itemsize) {
 | 
			
		||||
    auto ndim = shape.size();
 | 
			
		||||
    std::vector<ssize_t> strides(ndim, itemsize);
 | 
			
		||||
    for (size_t i = 1; i < ndim; ++i) {
 | 
			
		||||
        strides[i] = strides[i - 1] * shape[i - 1];
 | 
			
		||||
    }
 | 
			
		||||
    return strides;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T, typename SFINAE = void>
 | 
			
		||||
struct compare_buffer_info;
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_END(detail)
 | 
			
		||||
 | 
			
		||||
/// Information record describing a Python buffer object
 | 
			
		||||
struct buffer_info {
 | 
			
		||||
    void *ptr = nullptr;          // Pointer to the underlying storage
 | 
			
		||||
    ssize_t itemsize = 0;         // Size of individual items in bytes
 | 
			
		||||
    ssize_t size = 0;             // Total number of entries
 | 
			
		||||
    std::string format;           // For homogeneous buffers, this should be set to
 | 
			
		||||
                                  // format_descriptor<T>::format()
 | 
			
		||||
    ssize_t ndim = 0;             // Number of dimensions
 | 
			
		||||
    std::vector<ssize_t> shape;   // Shape of the tensor (1 entry per dimension)
 | 
			
		||||
    std::vector<ssize_t> strides; // Number of bytes between adjacent entries
 | 
			
		||||
                                  // (for each per dimension)
 | 
			
		||||
    bool readonly = false;        // flag to indicate if the underlying storage may be written to
 | 
			
		||||
 | 
			
		||||
    buffer_info() = default;
 | 
			
		||||
 | 
			
		||||
    buffer_info(void *ptr,
 | 
			
		||||
                ssize_t itemsize,
 | 
			
		||||
                const std::string &format,
 | 
			
		||||
                ssize_t ndim,
 | 
			
		||||
                detail::any_container<ssize_t> shape_in,
 | 
			
		||||
                detail::any_container<ssize_t> strides_in,
 | 
			
		||||
                bool readonly = false)
 | 
			
		||||
        : ptr(ptr), itemsize(itemsize), size(1), format(format), ndim(ndim),
 | 
			
		||||
          shape(std::move(shape_in)), strides(std::move(strides_in)), readonly(readonly) {
 | 
			
		||||
        if (ndim != (ssize_t) shape.size() || ndim != (ssize_t) strides.size()) {
 | 
			
		||||
            pybind11_fail("buffer_info: ndim doesn't match shape and/or strides length");
 | 
			
		||||
        }
 | 
			
		||||
        for (size_t i = 0; i < (size_t) ndim; ++i) {
 | 
			
		||||
            size *= shape[i];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    buffer_info(T *ptr,
 | 
			
		||||
                detail::any_container<ssize_t> shape_in,
 | 
			
		||||
                detail::any_container<ssize_t> strides_in,
 | 
			
		||||
                bool readonly = false)
 | 
			
		||||
        : buffer_info(private_ctr_tag(),
 | 
			
		||||
                      ptr,
 | 
			
		||||
                      sizeof(T),
 | 
			
		||||
                      format_descriptor<T>::format(),
 | 
			
		||||
                      static_cast<ssize_t>(shape_in->size()),
 | 
			
		||||
                      std::move(shape_in),
 | 
			
		||||
                      std::move(strides_in),
 | 
			
		||||
                      readonly) {}
 | 
			
		||||
 | 
			
		||||
    buffer_info(void *ptr,
 | 
			
		||||
                ssize_t itemsize,
 | 
			
		||||
                const std::string &format,
 | 
			
		||||
                ssize_t size,
 | 
			
		||||
                bool readonly = false)
 | 
			
		||||
        : buffer_info(ptr, itemsize, format, 1, {size}, {itemsize}, readonly) {}
 | 
			
		||||
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    buffer_info(T *ptr, ssize_t size, bool readonly = false)
 | 
			
		||||
        : buffer_info(ptr, sizeof(T), format_descriptor<T>::format(), size, readonly) {}
 | 
			
		||||
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    buffer_info(const T *ptr, ssize_t size, bool readonly = true)
 | 
			
		||||
        : buffer_info(
 | 
			
		||||
            const_cast<T *>(ptr), sizeof(T), format_descriptor<T>::format(), size, readonly) {}
 | 
			
		||||
 | 
			
		||||
    explicit buffer_info(Py_buffer *view, bool ownview = true)
 | 
			
		||||
        : buffer_info(
 | 
			
		||||
            view->buf,
 | 
			
		||||
            view->itemsize,
 | 
			
		||||
            view->format,
 | 
			
		||||
            view->ndim,
 | 
			
		||||
            {view->shape, view->shape + view->ndim},
 | 
			
		||||
            /* Though buffer::request() requests PyBUF_STRIDES, ctypes objects
 | 
			
		||||
             * ignore this flag and return a view with NULL strides.
 | 
			
		||||
             * When strides are NULL, build them manually.  */
 | 
			
		||||
            view->strides
 | 
			
		||||
                ? std::vector<ssize_t>(view->strides, view->strides + view->ndim)
 | 
			
		||||
                : detail::c_strides({view->shape, view->shape + view->ndim}, view->itemsize),
 | 
			
		||||
            (view->readonly != 0)) {
 | 
			
		||||
        // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)
 | 
			
		||||
        this->m_view = view;
 | 
			
		||||
        // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)
 | 
			
		||||
        this->ownview = ownview;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    buffer_info(const buffer_info &) = delete;
 | 
			
		||||
    buffer_info &operator=(const buffer_info &) = delete;
 | 
			
		||||
 | 
			
		||||
    buffer_info(buffer_info &&other) noexcept { (*this) = std::move(other); }
 | 
			
		||||
 | 
			
		||||
    buffer_info &operator=(buffer_info &&rhs) noexcept {
 | 
			
		||||
        ptr = rhs.ptr;
 | 
			
		||||
        itemsize = rhs.itemsize;
 | 
			
		||||
        size = rhs.size;
 | 
			
		||||
        format = std::move(rhs.format);
 | 
			
		||||
        ndim = rhs.ndim;
 | 
			
		||||
        shape = std::move(rhs.shape);
 | 
			
		||||
        strides = std::move(rhs.strides);
 | 
			
		||||
        std::swap(m_view, rhs.m_view);
 | 
			
		||||
        std::swap(ownview, rhs.ownview);
 | 
			
		||||
        readonly = rhs.readonly;
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~buffer_info() {
 | 
			
		||||
        if (m_view && ownview) {
 | 
			
		||||
            PyBuffer_Release(m_view);
 | 
			
		||||
            delete m_view;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Py_buffer *view() const { return m_view; }
 | 
			
		||||
    Py_buffer *&view() { return m_view; }
 | 
			
		||||
 | 
			
		||||
    /* True if the buffer item type is equivalent to `T`. */
 | 
			
		||||
    // To define "equivalent" by example:
 | 
			
		||||
    // `buffer_info::item_type_is_equivalent_to<int>(b)` and
 | 
			
		||||
    // `buffer_info::item_type_is_equivalent_to<long>(b)` may both be true
 | 
			
		||||
    // on some platforms, but `int` and `unsigned` will never be equivalent.
 | 
			
		||||
    // For the ground truth, please inspect `detail::compare_buffer_info<>`.
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    bool item_type_is_equivalent_to() const {
 | 
			
		||||
        return detail::compare_buffer_info<T>::compare(*this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    struct private_ctr_tag {};
 | 
			
		||||
 | 
			
		||||
    buffer_info(private_ctr_tag,
 | 
			
		||||
                void *ptr,
 | 
			
		||||
                ssize_t itemsize,
 | 
			
		||||
                const std::string &format,
 | 
			
		||||
                ssize_t ndim,
 | 
			
		||||
                detail::any_container<ssize_t> &&shape_in,
 | 
			
		||||
                detail::any_container<ssize_t> &&strides_in,
 | 
			
		||||
                bool readonly)
 | 
			
		||||
        : buffer_info(
 | 
			
		||||
            ptr, itemsize, format, ndim, std::move(shape_in), std::move(strides_in), readonly) {}
 | 
			
		||||
 | 
			
		||||
    Py_buffer *m_view = nullptr;
 | 
			
		||||
    bool ownview = false;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(detail)
 | 
			
		||||
 | 
			
		||||
template <typename T, typename SFINAE>
 | 
			
		||||
struct compare_buffer_info {
 | 
			
		||||
    static bool compare(const buffer_info &b) {
 | 
			
		||||
        // NOLINTNEXTLINE(bugprone-sizeof-expression) Needed for `PyObject *`
 | 
			
		||||
        return b.format == format_descriptor<T>::format() && b.itemsize == (ssize_t) sizeof(T);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct compare_buffer_info<T, detail::enable_if_t<std::is_integral<T>::value>> {
 | 
			
		||||
    static bool compare(const buffer_info &b) {
 | 
			
		||||
        return (size_t) b.itemsize == sizeof(T)
 | 
			
		||||
               && (b.format == format_descriptor<T>::value
 | 
			
		||||
                   || ((sizeof(T) == sizeof(long))
 | 
			
		||||
                       && b.format == (std::is_unsigned<T>::value ? "L" : "l"))
 | 
			
		||||
                   || ((sizeof(T) == sizeof(size_t))
 | 
			
		||||
                       && b.format == (std::is_unsigned<T>::value ? "N" : "n")));
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_END(detail)
 | 
			
		||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
 | 
			
		||||
							
								
								
									
										1704
									
								
								3rdparty/pybind11/include/pybind11/cast.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1704
									
								
								3rdparty/pybind11/include/pybind11/cast.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										225
									
								
								3rdparty/pybind11/include/pybind11/chrono.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										225
									
								
								3rdparty/pybind11/include/pybind11/chrono.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,225 @@
 | 
			
		||||
/*
 | 
			
		||||
    pybind11/chrono.h: Transparent conversion between std::chrono and python's datetime
 | 
			
		||||
 | 
			
		||||
    Copyright (c) 2016 Trent Houliston <trent@houliston.me> and
 | 
			
		||||
                       Wenzel Jakob <wenzel.jakob@epfl.ch>
 | 
			
		||||
 | 
			
		||||
    All rights reserved. Use of this source code is governed by a
 | 
			
		||||
    BSD-style license that can be found in the LICENSE file.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "pybind11.h"
 | 
			
		||||
 | 
			
		||||
#include <chrono>
 | 
			
		||||
#include <cmath>
 | 
			
		||||
#include <ctime>
 | 
			
		||||
#include <datetime.h>
 | 
			
		||||
#include <mutex>
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(detail)
 | 
			
		||||
 | 
			
		||||
template <typename type>
 | 
			
		||||
class duration_caster {
 | 
			
		||||
public:
 | 
			
		||||
    using rep = typename type::rep;
 | 
			
		||||
    using period = typename type::period;
 | 
			
		||||
 | 
			
		||||
    // signed 25 bits required by the standard.
 | 
			
		||||
    using days = std::chrono::duration<int_least32_t, std::ratio<86400>>;
 | 
			
		||||
 | 
			
		||||
    bool load(handle src, bool) {
 | 
			
		||||
        using namespace std::chrono;
 | 
			
		||||
 | 
			
		||||
        // Lazy initialise the PyDateTime import
 | 
			
		||||
        if (!PyDateTimeAPI) {
 | 
			
		||||
            PyDateTime_IMPORT;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!src) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        // If invoked with datetime.delta object
 | 
			
		||||
        if (PyDelta_Check(src.ptr())) {
 | 
			
		||||
            value = type(duration_cast<duration<rep, period>>(
 | 
			
		||||
                days(PyDateTime_DELTA_GET_DAYS(src.ptr()))
 | 
			
		||||
                + seconds(PyDateTime_DELTA_GET_SECONDS(src.ptr()))
 | 
			
		||||
                + microseconds(PyDateTime_DELTA_GET_MICROSECONDS(src.ptr()))));
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        // If invoked with a float we assume it is seconds and convert
 | 
			
		||||
        if (PyFloat_Check(src.ptr())) {
 | 
			
		||||
            value = type(duration_cast<duration<rep, period>>(
 | 
			
		||||
                duration<double>(PyFloat_AsDouble(src.ptr()))));
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If this is a duration just return it back
 | 
			
		||||
    static const std::chrono::duration<rep, period> &
 | 
			
		||||
    get_duration(const std::chrono::duration<rep, period> &src) {
 | 
			
		||||
        return src;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If this is a time_point get the time_since_epoch
 | 
			
		||||
    template <typename Clock>
 | 
			
		||||
    static std::chrono::duration<rep, period>
 | 
			
		||||
    get_duration(const std::chrono::time_point<Clock, std::chrono::duration<rep, period>> &src) {
 | 
			
		||||
        return src.time_since_epoch();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static handle cast(const type &src, return_value_policy /* policy */, handle /* parent */) {
 | 
			
		||||
        using namespace std::chrono;
 | 
			
		||||
 | 
			
		||||
        // Use overloaded function to get our duration from our source
 | 
			
		||||
        // Works out if it is a duration or time_point and get the duration
 | 
			
		||||
        auto d = get_duration(src);
 | 
			
		||||
 | 
			
		||||
        // Lazy initialise the PyDateTime import
 | 
			
		||||
        if (!PyDateTimeAPI) {
 | 
			
		||||
            PyDateTime_IMPORT;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Declare these special duration types so the conversions happen with the correct
 | 
			
		||||
        // primitive types (int)
 | 
			
		||||
        using dd_t = duration<int, std::ratio<86400>>;
 | 
			
		||||
        using ss_t = duration<int, std::ratio<1>>;
 | 
			
		||||
        using us_t = duration<int, std::micro>;
 | 
			
		||||
 | 
			
		||||
        auto dd = duration_cast<dd_t>(d);
 | 
			
		||||
        auto subd = d - dd;
 | 
			
		||||
        auto ss = duration_cast<ss_t>(subd);
 | 
			
		||||
        auto us = duration_cast<us_t>(subd - ss);
 | 
			
		||||
        return PyDelta_FromDSU(dd.count(), ss.count(), us.count());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    PYBIND11_TYPE_CASTER(type, const_name("datetime.timedelta"));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
inline std::tm *localtime_thread_safe(const std::time_t *time, std::tm *buf) {
 | 
			
		||||
#if (defined(__STDC_LIB_EXT1__) && defined(__STDC_WANT_LIB_EXT1__)) || defined(_MSC_VER)
 | 
			
		||||
    if (localtime_s(buf, time))
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    return buf;
 | 
			
		||||
#else
 | 
			
		||||
    static std::mutex mtx;
 | 
			
		||||
    std::lock_guard<std::mutex> lock(mtx);
 | 
			
		||||
    std::tm *tm_ptr = std::localtime(time);
 | 
			
		||||
    if (tm_ptr != nullptr) {
 | 
			
		||||
        *buf = *tm_ptr;
 | 
			
		||||
    }
 | 
			
		||||
    return tm_ptr;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// This is for casting times on the system clock into datetime.datetime instances
 | 
			
		||||
template <typename Duration>
 | 
			
		||||
class type_caster<std::chrono::time_point<std::chrono::system_clock, Duration>> {
 | 
			
		||||
public:
 | 
			
		||||
    using type = std::chrono::time_point<std::chrono::system_clock, Duration>;
 | 
			
		||||
    bool load(handle src, bool) {
 | 
			
		||||
        using namespace std::chrono;
 | 
			
		||||
 | 
			
		||||
        // Lazy initialise the PyDateTime import
 | 
			
		||||
        if (!PyDateTimeAPI) {
 | 
			
		||||
            PyDateTime_IMPORT;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!src) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        std::tm cal;
 | 
			
		||||
        microseconds msecs;
 | 
			
		||||
 | 
			
		||||
        if (PyDateTime_Check(src.ptr())) {
 | 
			
		||||
            cal.tm_sec = PyDateTime_DATE_GET_SECOND(src.ptr());
 | 
			
		||||
            cal.tm_min = PyDateTime_DATE_GET_MINUTE(src.ptr());
 | 
			
		||||
            cal.tm_hour = PyDateTime_DATE_GET_HOUR(src.ptr());
 | 
			
		||||
            cal.tm_mday = PyDateTime_GET_DAY(src.ptr());
 | 
			
		||||
            cal.tm_mon = PyDateTime_GET_MONTH(src.ptr()) - 1;
 | 
			
		||||
            cal.tm_year = PyDateTime_GET_YEAR(src.ptr()) - 1900;
 | 
			
		||||
            cal.tm_isdst = -1;
 | 
			
		||||
            msecs = microseconds(PyDateTime_DATE_GET_MICROSECOND(src.ptr()));
 | 
			
		||||
        } else if (PyDate_Check(src.ptr())) {
 | 
			
		||||
            cal.tm_sec = 0;
 | 
			
		||||
            cal.tm_min = 0;
 | 
			
		||||
            cal.tm_hour = 0;
 | 
			
		||||
            cal.tm_mday = PyDateTime_GET_DAY(src.ptr());
 | 
			
		||||
            cal.tm_mon = PyDateTime_GET_MONTH(src.ptr()) - 1;
 | 
			
		||||
            cal.tm_year = PyDateTime_GET_YEAR(src.ptr()) - 1900;
 | 
			
		||||
            cal.tm_isdst = -1;
 | 
			
		||||
            msecs = microseconds(0);
 | 
			
		||||
        } else if (PyTime_Check(src.ptr())) {
 | 
			
		||||
            cal.tm_sec = PyDateTime_TIME_GET_SECOND(src.ptr());
 | 
			
		||||
            cal.tm_min = PyDateTime_TIME_GET_MINUTE(src.ptr());
 | 
			
		||||
            cal.tm_hour = PyDateTime_TIME_GET_HOUR(src.ptr());
 | 
			
		||||
            cal.tm_mday = 1;  // This date (day, month, year) = (1, 0, 70)
 | 
			
		||||
            cal.tm_mon = 0;   // represents 1-Jan-1970, which is the first
 | 
			
		||||
            cal.tm_year = 70; // earliest available date for Python's datetime
 | 
			
		||||
            cal.tm_isdst = -1;
 | 
			
		||||
            msecs = microseconds(PyDateTime_TIME_GET_MICROSECOND(src.ptr()));
 | 
			
		||||
        } else {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        value = time_point_cast<Duration>(system_clock::from_time_t(std::mktime(&cal)) + msecs);
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static handle cast(const std::chrono::time_point<std::chrono::system_clock, Duration> &src,
 | 
			
		||||
                       return_value_policy /* policy */,
 | 
			
		||||
                       handle /* parent */) {
 | 
			
		||||
        using namespace std::chrono;
 | 
			
		||||
 | 
			
		||||
        // Lazy initialise the PyDateTime import
 | 
			
		||||
        if (!PyDateTimeAPI) {
 | 
			
		||||
            PyDateTime_IMPORT;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Get out microseconds, and make sure they are positive, to avoid bug in eastern
 | 
			
		||||
        // hemisphere time zones (cfr. https://github.com/pybind/pybind11/issues/2417)
 | 
			
		||||
        using us_t = duration<int, std::micro>;
 | 
			
		||||
        auto us = duration_cast<us_t>(src.time_since_epoch() % seconds(1));
 | 
			
		||||
        if (us.count() < 0) {
 | 
			
		||||
            us += seconds(1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Subtract microseconds BEFORE `system_clock::to_time_t`, because:
 | 
			
		||||
        // > If std::time_t has lower precision, it is implementation-defined whether the value is
 | 
			
		||||
        // rounded or truncated. (https://en.cppreference.com/w/cpp/chrono/system_clock/to_time_t)
 | 
			
		||||
        std::time_t tt
 | 
			
		||||
            = system_clock::to_time_t(time_point_cast<system_clock::duration>(src - us));
 | 
			
		||||
 | 
			
		||||
        std::tm localtime;
 | 
			
		||||
        std::tm *localtime_ptr = localtime_thread_safe(&tt, &localtime);
 | 
			
		||||
        if (!localtime_ptr) {
 | 
			
		||||
            throw cast_error("Unable to represent system_clock in local time");
 | 
			
		||||
        }
 | 
			
		||||
        return PyDateTime_FromDateAndTime(localtime.tm_year + 1900,
 | 
			
		||||
                                          localtime.tm_mon + 1,
 | 
			
		||||
                                          localtime.tm_mday,
 | 
			
		||||
                                          localtime.tm_hour,
 | 
			
		||||
                                          localtime.tm_min,
 | 
			
		||||
                                          localtime.tm_sec,
 | 
			
		||||
                                          us.count());
 | 
			
		||||
    }
 | 
			
		||||
    PYBIND11_TYPE_CASTER(type, const_name("datetime.datetime"));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Other clocks that are not the system clock are not measured as datetime.datetime objects
 | 
			
		||||
// since they are not measured on calendar time. So instead we just make them timedeltas
 | 
			
		||||
// Or if they have passed us a time as a float we convert that
 | 
			
		||||
template <typename Clock, typename Duration>
 | 
			
		||||
class type_caster<std::chrono::time_point<Clock, Duration>>
 | 
			
		||||
    : public duration_caster<std::chrono::time_point<Clock, Duration>> {};
 | 
			
		||||
 | 
			
		||||
template <typename Rep, typename Period>
 | 
			
		||||
class type_caster<std::chrono::duration<Rep, Period>>
 | 
			
		||||
    : public duration_caster<std::chrono::duration<Rep, Period>> {};
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_END(detail)
 | 
			
		||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
 | 
			
		||||
							
								
								
									
										2
									
								
								3rdparty/pybind11/include/pybind11/common.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								3rdparty/pybind11/include/pybind11/common.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
#include "detail/common.h"
 | 
			
		||||
#warning "Including 'common.h' is deprecated. It will be removed in v3.0. Use 'pybind11.h'."
 | 
			
		||||
							
								
								
									
										74
									
								
								3rdparty/pybind11/include/pybind11/complex.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								3rdparty/pybind11/include/pybind11/complex.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,74 @@
 | 
			
		||||
/*
 | 
			
		||||
    pybind11/complex.h: Complex number support
 | 
			
		||||
 | 
			
		||||
    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
 | 
			
		||||
 | 
			
		||||
    All rights reserved. Use of this source code is governed by a
 | 
			
		||||
    BSD-style license that can be found in the LICENSE file.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "pybind11.h"
 | 
			
		||||
 | 
			
		||||
#include <complex>
 | 
			
		||||
 | 
			
		||||
/// glibc defines I as a macro which breaks things, e.g., boost template names
 | 
			
		||||
#ifdef I
 | 
			
		||||
#    undef I
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct format_descriptor<std::complex<T>, detail::enable_if_t<std::is_floating_point<T>::value>> {
 | 
			
		||||
    static constexpr const char c = format_descriptor<T>::c;
 | 
			
		||||
    static constexpr const char value[3] = {'Z', c, '\0'};
 | 
			
		||||
    static std::string format() { return std::string(value); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#ifndef PYBIND11_CPP17
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
constexpr const char
 | 
			
		||||
    format_descriptor<std::complex<T>,
 | 
			
		||||
                      detail::enable_if_t<std::is_floating_point<T>::value>>::value[3];
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(detail)
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct is_fmt_numeric<std::complex<T>, detail::enable_if_t<std::is_floating_point<T>::value>> {
 | 
			
		||||
    static constexpr bool value = true;
 | 
			
		||||
    static constexpr int index = is_fmt_numeric<T>::index + 3;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
class type_caster<std::complex<T>> {
 | 
			
		||||
public:
 | 
			
		||||
    bool load(handle src, bool convert) {
 | 
			
		||||
        if (!src) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (!convert && !PyComplex_Check(src.ptr())) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        Py_complex result = PyComplex_AsCComplex(src.ptr());
 | 
			
		||||
        if (result.real == -1.0 && PyErr_Occurred()) {
 | 
			
		||||
            PyErr_Clear();
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        value = std::complex<T>((T) result.real, (T) result.imag);
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static handle
 | 
			
		||||
    cast(const std::complex<T> &src, return_value_policy /* policy */, handle /* parent */) {
 | 
			
		||||
        return PyComplex_FromDoubles((double) src.real(), (double) src.imag());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    PYBIND11_TYPE_CASTER(std::complex<T>, const_name("complex"));
 | 
			
		||||
};
 | 
			
		||||
PYBIND11_NAMESPACE_END(detail)
 | 
			
		||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
 | 
			
		||||
							
								
								
									
										743
									
								
								3rdparty/pybind11/include/pybind11/detail/class.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										743
									
								
								3rdparty/pybind11/include/pybind11/detail/class.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,743 @@
 | 
			
		||||
/*
 | 
			
		||||
    pybind11/detail/class.h: Python C API implementation details for py::class_
 | 
			
		||||
 | 
			
		||||
    Copyright (c) 2017 Wenzel Jakob <wenzel.jakob@epfl.ch>
 | 
			
		||||
 | 
			
		||||
    All rights reserved. Use of this source code is governed by a
 | 
			
		||||
    BSD-style license that can be found in the LICENSE file.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "../attr.h"
 | 
			
		||||
#include "../options.h"
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(detail)
 | 
			
		||||
 | 
			
		||||
#if !defined(PYPY_VERSION)
 | 
			
		||||
#    define PYBIND11_BUILTIN_QUALNAME
 | 
			
		||||
#    define PYBIND11_SET_OLDPY_QUALNAME(obj, nameobj)
 | 
			
		||||
#else
 | 
			
		||||
// In PyPy, we still set __qualname__ so that we can produce reliable function type
 | 
			
		||||
// signatures; in CPython this macro expands to nothing:
 | 
			
		||||
#    define PYBIND11_SET_OLDPY_QUALNAME(obj, nameobj)                                             \
 | 
			
		||||
        setattr((PyObject *) obj, "__qualname__", nameobj)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
inline std::string get_fully_qualified_tp_name(PyTypeObject *type) {
 | 
			
		||||
#if !defined(PYPY_VERSION)
 | 
			
		||||
    return type->tp_name;
 | 
			
		||||
#else
 | 
			
		||||
    auto module_name = handle((PyObject *) type).attr("__module__").cast<std::string>();
 | 
			
		||||
    if (module_name == PYBIND11_BUILTINS_MODULE)
 | 
			
		||||
        return type->tp_name;
 | 
			
		||||
    else
 | 
			
		||||
        return std::move(module_name) + "." + type->tp_name;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline PyTypeObject *type_incref(PyTypeObject *type) {
 | 
			
		||||
    Py_INCREF(type);
 | 
			
		||||
    return type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if !defined(PYPY_VERSION)
 | 
			
		||||
 | 
			
		||||
/// `pybind11_static_property.__get__()`: Always pass the class instead of the instance.
 | 
			
		||||
extern "C" inline PyObject *pybind11_static_get(PyObject *self, PyObject * /*ob*/, PyObject *cls) {
 | 
			
		||||
    return PyProperty_Type.tp_descr_get(self, cls, cls);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// `pybind11_static_property.__set__()`: Just like the above `__get__()`.
 | 
			
		||||
extern "C" inline int pybind11_static_set(PyObject *self, PyObject *obj, PyObject *value) {
 | 
			
		||||
    PyObject *cls = PyType_Check(obj) ? obj : (PyObject *) Py_TYPE(obj);
 | 
			
		||||
    return PyProperty_Type.tp_descr_set(self, cls, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Forward declaration to use in `make_static_property_type()`
 | 
			
		||||
inline void enable_dynamic_attributes(PyHeapTypeObject *heap_type);
 | 
			
		||||
 | 
			
		||||
/** A `static_property` is the same as a `property` but the `__get__()` and `__set__()`
 | 
			
		||||
    methods are modified to always use the object type instead of a concrete instance.
 | 
			
		||||
    Return value: New reference. */
 | 
			
		||||
inline PyTypeObject *make_static_property_type() {
 | 
			
		||||
    constexpr auto *name = "pybind11_static_property";
 | 
			
		||||
    auto name_obj = reinterpret_steal<object>(PYBIND11_FROM_STRING(name));
 | 
			
		||||
 | 
			
		||||
    /* Danger zone: from now (and until PyType_Ready), make sure to
 | 
			
		||||
       issue no Python C API calls which could potentially invoke the
 | 
			
		||||
       garbage collector (the GC will call type_traverse(), which will in
 | 
			
		||||
       turn find the newly constructed type in an invalid state) */
 | 
			
		||||
    auto *heap_type = (PyHeapTypeObject *) PyType_Type.tp_alloc(&PyType_Type, 0);
 | 
			
		||||
    if (!heap_type) {
 | 
			
		||||
        pybind11_fail("make_static_property_type(): error allocating type!");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    heap_type->ht_name = name_obj.inc_ref().ptr();
 | 
			
		||||
#    ifdef PYBIND11_BUILTIN_QUALNAME
 | 
			
		||||
    heap_type->ht_qualname = name_obj.inc_ref().ptr();
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
    auto *type = &heap_type->ht_type;
 | 
			
		||||
    type->tp_name = name;
 | 
			
		||||
    type->tp_base = type_incref(&PyProperty_Type);
 | 
			
		||||
    type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;
 | 
			
		||||
    type->tp_descr_get = pybind11_static_get;
 | 
			
		||||
    type->tp_descr_set = pybind11_static_set;
 | 
			
		||||
 | 
			
		||||
    if (PyType_Ready(type) < 0) {
 | 
			
		||||
        pybind11_fail("make_static_property_type(): failure in PyType_Ready()!");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#    if PY_VERSION_HEX >= 0x030C0000
 | 
			
		||||
    // PRE 3.12 FEATURE FREEZE. PLEASE REVIEW AFTER FREEZE.
 | 
			
		||||
    // Since Python-3.12 property-derived types are required to
 | 
			
		||||
    // have dynamic attributes (to set `__doc__`)
 | 
			
		||||
    enable_dynamic_attributes(heap_type);
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
    setattr((PyObject *) type, "__module__", str("pybind11_builtins"));
 | 
			
		||||
    PYBIND11_SET_OLDPY_QUALNAME(type, name_obj);
 | 
			
		||||
 | 
			
		||||
    return type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else // PYPY
 | 
			
		||||
 | 
			
		||||
/** PyPy has some issues with the above C API, so we evaluate Python code instead.
 | 
			
		||||
    This function will only be called once so performance isn't really a concern.
 | 
			
		||||
    Return value: New reference. */
 | 
			
		||||
inline PyTypeObject *make_static_property_type() {
 | 
			
		||||
    auto d = dict();
 | 
			
		||||
    PyObject *result = PyRun_String(R"(\
 | 
			
		||||
class pybind11_static_property(property):
 | 
			
		||||
    def __get__(self, obj, cls):
 | 
			
		||||
        return property.__get__(self, cls, cls)
 | 
			
		||||
 | 
			
		||||
    def __set__(self, obj, value):
 | 
			
		||||
        cls = obj if isinstance(obj, type) else type(obj)
 | 
			
		||||
        property.__set__(self, cls, value)
 | 
			
		||||
)",
 | 
			
		||||
                                    Py_file_input,
 | 
			
		||||
                                    d.ptr(),
 | 
			
		||||
                                    d.ptr());
 | 
			
		||||
    if (result == nullptr)
 | 
			
		||||
        throw error_already_set();
 | 
			
		||||
    Py_DECREF(result);
 | 
			
		||||
    return (PyTypeObject *) d["pybind11_static_property"].cast<object>().release().ptr();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // PYPY
 | 
			
		||||
 | 
			
		||||
/** Types with static properties need to handle `Type.static_prop = x` in a specific way.
 | 
			
		||||
    By default, Python replaces the `static_property` itself, but for wrapped C++ types
 | 
			
		||||
    we need to call `static_property.__set__()` in order to propagate the new value to
 | 
			
		||||
    the underlying C++ data structure. */
 | 
			
		||||
extern "C" inline int pybind11_meta_setattro(PyObject *obj, PyObject *name, PyObject *value) {
 | 
			
		||||
    // Use `_PyType_Lookup()` instead of `PyObject_GetAttr()` in order to get the raw
 | 
			
		||||
    // descriptor (`property`) instead of calling `tp_descr_get` (`property.__get__()`).
 | 
			
		||||
    PyObject *descr = _PyType_Lookup((PyTypeObject *) obj, name);
 | 
			
		||||
 | 
			
		||||
    // The following assignment combinations are possible:
 | 
			
		||||
    //   1. `Type.static_prop = value`             --> descr_set: `Type.static_prop.__set__(value)`
 | 
			
		||||
    //   2. `Type.static_prop = other_static_prop` --> setattro:  replace existing `static_prop`
 | 
			
		||||
    //   3. `Type.regular_attribute = value`       --> setattro:  regular attribute assignment
 | 
			
		||||
    auto *const static_prop = (PyObject *) get_internals().static_property_type;
 | 
			
		||||
    const auto call_descr_set = (descr != nullptr) && (value != nullptr)
 | 
			
		||||
                                && (PyObject_IsInstance(descr, static_prop) != 0)
 | 
			
		||||
                                && (PyObject_IsInstance(value, static_prop) == 0);
 | 
			
		||||
    if (call_descr_set) {
 | 
			
		||||
        // Call `static_property.__set__()` instead of replacing the `static_property`.
 | 
			
		||||
#if !defined(PYPY_VERSION)
 | 
			
		||||
        return Py_TYPE(descr)->tp_descr_set(descr, obj, value);
 | 
			
		||||
#else
 | 
			
		||||
        if (PyObject *result = PyObject_CallMethod(descr, "__set__", "OO", obj, value)) {
 | 
			
		||||
            Py_DECREF(result);
 | 
			
		||||
            return 0;
 | 
			
		||||
        } else {
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
    } else {
 | 
			
		||||
        // Replace existing attribute.
 | 
			
		||||
        return PyType_Type.tp_setattro(obj, name, value);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Python 3's PyInstanceMethod_Type hides itself via its tp_descr_get, which prevents aliasing
 | 
			
		||||
 * methods via cls.attr("m2") = cls.attr("m1"): instead the tp_descr_get returns a plain function,
 | 
			
		||||
 * when called on a class, or a PyMethod, when called on an instance.  Override that behaviour here
 | 
			
		||||
 * to do a special case bypass for PyInstanceMethod_Types.
 | 
			
		||||
 */
 | 
			
		||||
extern "C" inline PyObject *pybind11_meta_getattro(PyObject *obj, PyObject *name) {
 | 
			
		||||
    PyObject *descr = _PyType_Lookup((PyTypeObject *) obj, name);
 | 
			
		||||
    if (descr && PyInstanceMethod_Check(descr)) {
 | 
			
		||||
        Py_INCREF(descr);
 | 
			
		||||
        return descr;
 | 
			
		||||
    }
 | 
			
		||||
    return PyType_Type.tp_getattro(obj, name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// metaclass `__call__` function that is used to create all pybind11 objects.
 | 
			
		||||
extern "C" inline PyObject *pybind11_meta_call(PyObject *type, PyObject *args, PyObject *kwargs) {
 | 
			
		||||
 | 
			
		||||
    // use the default metaclass call to create/initialize the object
 | 
			
		||||
    PyObject *self = PyType_Type.tp_call(type, args, kwargs);
 | 
			
		||||
    if (self == nullptr) {
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // This must be a pybind11 instance
 | 
			
		||||
    auto *instance = reinterpret_cast<detail::instance *>(self);
 | 
			
		||||
 | 
			
		||||
    // Ensure that the base __init__ function(s) were called
 | 
			
		||||
    for (const auto &vh : values_and_holders(instance)) {
 | 
			
		||||
        if (!vh.holder_constructed()) {
 | 
			
		||||
            PyErr_Format(PyExc_TypeError,
 | 
			
		||||
                         "%.200s.__init__() must be called when overriding __init__",
 | 
			
		||||
                         get_fully_qualified_tp_name(vh.type->type).c_str());
 | 
			
		||||
            Py_DECREF(self);
 | 
			
		||||
            return nullptr;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Cleanup the type-info for a pybind11-registered type.
 | 
			
		||||
extern "C" inline void pybind11_meta_dealloc(PyObject *obj) {
 | 
			
		||||
    auto *type = (PyTypeObject *) obj;
 | 
			
		||||
    auto &internals = get_internals();
 | 
			
		||||
 | 
			
		||||
    // A pybind11-registered type will:
 | 
			
		||||
    // 1) be found in internals.registered_types_py
 | 
			
		||||
    // 2) have exactly one associated `detail::type_info`
 | 
			
		||||
    auto found_type = internals.registered_types_py.find(type);
 | 
			
		||||
    if (found_type != internals.registered_types_py.end() && found_type->second.size() == 1
 | 
			
		||||
        && found_type->second[0]->type == type) {
 | 
			
		||||
 | 
			
		||||
        auto *tinfo = found_type->second[0];
 | 
			
		||||
        auto tindex = std::type_index(*tinfo->cpptype);
 | 
			
		||||
        internals.direct_conversions.erase(tindex);
 | 
			
		||||
 | 
			
		||||
        if (tinfo->module_local) {
 | 
			
		||||
            get_local_internals().registered_types_cpp.erase(tindex);
 | 
			
		||||
        } else {
 | 
			
		||||
            internals.registered_types_cpp.erase(tindex);
 | 
			
		||||
        }
 | 
			
		||||
        internals.registered_types_py.erase(tinfo->type);
 | 
			
		||||
 | 
			
		||||
        // Actually just `std::erase_if`, but that's only available in C++20
 | 
			
		||||
        auto &cache = internals.inactive_override_cache;
 | 
			
		||||
        for (auto it = cache.begin(), last = cache.end(); it != last;) {
 | 
			
		||||
            if (it->first == (PyObject *) tinfo->type) {
 | 
			
		||||
                it = cache.erase(it);
 | 
			
		||||
            } else {
 | 
			
		||||
                ++it;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        delete tinfo;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    PyType_Type.tp_dealloc(obj);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** This metaclass is assigned by default to all pybind11 types and is required in order
 | 
			
		||||
    for static properties to function correctly. Users may override this using `py::metaclass`.
 | 
			
		||||
    Return value: New reference. */
 | 
			
		||||
inline PyTypeObject *make_default_metaclass() {
 | 
			
		||||
    constexpr auto *name = "pybind11_type";
 | 
			
		||||
    auto name_obj = reinterpret_steal<object>(PYBIND11_FROM_STRING(name));
 | 
			
		||||
 | 
			
		||||
    /* Danger zone: from now (and until PyType_Ready), make sure to
 | 
			
		||||
       issue no Python C API calls which could potentially invoke the
 | 
			
		||||
       garbage collector (the GC will call type_traverse(), which will in
 | 
			
		||||
       turn find the newly constructed type in an invalid state) */
 | 
			
		||||
    auto *heap_type = (PyHeapTypeObject *) PyType_Type.tp_alloc(&PyType_Type, 0);
 | 
			
		||||
    if (!heap_type) {
 | 
			
		||||
        pybind11_fail("make_default_metaclass(): error allocating metaclass!");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    heap_type->ht_name = name_obj.inc_ref().ptr();
 | 
			
		||||
#ifdef PYBIND11_BUILTIN_QUALNAME
 | 
			
		||||
    heap_type->ht_qualname = name_obj.inc_ref().ptr();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    auto *type = &heap_type->ht_type;
 | 
			
		||||
    type->tp_name = name;
 | 
			
		||||
    type->tp_base = type_incref(&PyType_Type);
 | 
			
		||||
    type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;
 | 
			
		||||
 | 
			
		||||
    type->tp_call = pybind11_meta_call;
 | 
			
		||||
 | 
			
		||||
    type->tp_setattro = pybind11_meta_setattro;
 | 
			
		||||
    type->tp_getattro = pybind11_meta_getattro;
 | 
			
		||||
 | 
			
		||||
    type->tp_dealloc = pybind11_meta_dealloc;
 | 
			
		||||
 | 
			
		||||
    if (PyType_Ready(type) < 0) {
 | 
			
		||||
        pybind11_fail("make_default_metaclass(): failure in PyType_Ready()!");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setattr((PyObject *) type, "__module__", str("pybind11_builtins"));
 | 
			
		||||
    PYBIND11_SET_OLDPY_QUALNAME(type, name_obj);
 | 
			
		||||
 | 
			
		||||
    return type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// For multiple inheritance types we need to recursively register/deregister base pointers for any
 | 
			
		||||
/// base classes with pointers that are difference from the instance value pointer so that we can
 | 
			
		||||
/// correctly recognize an offset base class pointer. This calls a function with any offset base
 | 
			
		||||
/// ptrs.
 | 
			
		||||
inline void traverse_offset_bases(void *valueptr,
 | 
			
		||||
                                  const detail::type_info *tinfo,
 | 
			
		||||
                                  instance *self,
 | 
			
		||||
                                  bool (*f)(void * /*parentptr*/, instance * /*self*/)) {
 | 
			
		||||
    for (handle h : reinterpret_borrow<tuple>(tinfo->type->tp_bases)) {
 | 
			
		||||
        if (auto *parent_tinfo = get_type_info((PyTypeObject *) h.ptr())) {
 | 
			
		||||
            for (auto &c : parent_tinfo->implicit_casts) {
 | 
			
		||||
                if (c.first == tinfo->cpptype) {
 | 
			
		||||
                    auto *parentptr = c.second(valueptr);
 | 
			
		||||
                    if (parentptr != valueptr) {
 | 
			
		||||
                        f(parentptr, self);
 | 
			
		||||
                    }
 | 
			
		||||
                    traverse_offset_bases(parentptr, parent_tinfo, self, f);
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool register_instance_impl(void *ptr, instance *self) {
 | 
			
		||||
    get_internals().registered_instances.emplace(ptr, self);
 | 
			
		||||
    return true; // unused, but gives the same signature as the deregister func
 | 
			
		||||
}
 | 
			
		||||
inline bool deregister_instance_impl(void *ptr, instance *self) {
 | 
			
		||||
    auto ®istered_instances = get_internals().registered_instances;
 | 
			
		||||
    auto range = registered_instances.equal_range(ptr);
 | 
			
		||||
    for (auto it = range.first; it != range.second; ++it) {
 | 
			
		||||
        if (self == it->second) {
 | 
			
		||||
            registered_instances.erase(it);
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void register_instance(instance *self, void *valptr, const type_info *tinfo) {
 | 
			
		||||
    register_instance_impl(valptr, self);
 | 
			
		||||
    if (!tinfo->simple_ancestors) {
 | 
			
		||||
        traverse_offset_bases(valptr, tinfo, self, register_instance_impl);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool deregister_instance(instance *self, void *valptr, const type_info *tinfo) {
 | 
			
		||||
    bool ret = deregister_instance_impl(valptr, self);
 | 
			
		||||
    if (!tinfo->simple_ancestors) {
 | 
			
		||||
        traverse_offset_bases(valptr, tinfo, self, deregister_instance_impl);
 | 
			
		||||
    }
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Instance creation function for all pybind11 types. It allocates the internal instance layout
 | 
			
		||||
/// for holding C++ objects and holders.  Allocation is done lazily (the first time the instance is
 | 
			
		||||
/// cast to a reference or pointer), and initialization is done by an `__init__` function.
 | 
			
		||||
inline PyObject *make_new_instance(PyTypeObject *type) {
 | 
			
		||||
#if defined(PYPY_VERSION)
 | 
			
		||||
    // PyPy gets tp_basicsize wrong (issue 2482) under multiple inheritance when the first
 | 
			
		||||
    // inherited object is a plain Python type (i.e. not derived from an extension type).  Fix it.
 | 
			
		||||
    ssize_t instance_size = static_cast<ssize_t>(sizeof(instance));
 | 
			
		||||
    if (type->tp_basicsize < instance_size) {
 | 
			
		||||
        type->tp_basicsize = instance_size;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    PyObject *self = type->tp_alloc(type, 0);
 | 
			
		||||
    auto *inst = reinterpret_cast<instance *>(self);
 | 
			
		||||
    // Allocate the value/holder internals:
 | 
			
		||||
    inst->allocate_layout();
 | 
			
		||||
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Instance creation function for all pybind11 types. It only allocates space for the
 | 
			
		||||
/// C++ object, but doesn't call the constructor -- an `__init__` function must do that.
 | 
			
		||||
extern "C" inline PyObject *pybind11_object_new(PyTypeObject *type, PyObject *, PyObject *) {
 | 
			
		||||
    return make_new_instance(type);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// An `__init__` function constructs the C++ object. Users should provide at least one
 | 
			
		||||
/// of these using `py::init` or directly with `.def(__init__, ...)`. Otherwise, the
 | 
			
		||||
/// following default function will be used which simply throws an exception.
 | 
			
		||||
extern "C" inline int pybind11_object_init(PyObject *self, PyObject *, PyObject *) {
 | 
			
		||||
    PyTypeObject *type = Py_TYPE(self);
 | 
			
		||||
    std::string msg = get_fully_qualified_tp_name(type) + ": No constructor defined!";
 | 
			
		||||
    PyErr_SetString(PyExc_TypeError, msg.c_str());
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void add_patient(PyObject *nurse, PyObject *patient) {
 | 
			
		||||
    auto &internals = get_internals();
 | 
			
		||||
    auto *instance = reinterpret_cast<detail::instance *>(nurse);
 | 
			
		||||
    instance->has_patients = true;
 | 
			
		||||
    Py_INCREF(patient);
 | 
			
		||||
    internals.patients[nurse].push_back(patient);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void clear_patients(PyObject *self) {
 | 
			
		||||
    auto *instance = reinterpret_cast<detail::instance *>(self);
 | 
			
		||||
    auto &internals = get_internals();
 | 
			
		||||
    auto pos = internals.patients.find(self);
 | 
			
		||||
    assert(pos != internals.patients.end());
 | 
			
		||||
    // Clearing the patients can cause more Python code to run, which
 | 
			
		||||
    // can invalidate the iterator. Extract the vector of patients
 | 
			
		||||
    // from the unordered_map first.
 | 
			
		||||
    auto patients = std::move(pos->second);
 | 
			
		||||
    internals.patients.erase(pos);
 | 
			
		||||
    instance->has_patients = false;
 | 
			
		||||
    for (PyObject *&patient : patients) {
 | 
			
		||||
        Py_CLEAR(patient);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Clears all internal data from the instance and removes it from registered instances in
 | 
			
		||||
/// preparation for deallocation.
 | 
			
		||||
inline void clear_instance(PyObject *self) {
 | 
			
		||||
    auto *instance = reinterpret_cast<detail::instance *>(self);
 | 
			
		||||
 | 
			
		||||
    // Deallocate any values/holders, if present:
 | 
			
		||||
    for (auto &v_h : values_and_holders(instance)) {
 | 
			
		||||
        if (v_h) {
 | 
			
		||||
 | 
			
		||||
            // We have to deregister before we call dealloc because, for virtual MI types, we still
 | 
			
		||||
            // need to be able to get the parent pointers.
 | 
			
		||||
            if (v_h.instance_registered()
 | 
			
		||||
                && !deregister_instance(instance, v_h.value_ptr(), v_h.type)) {
 | 
			
		||||
                pybind11_fail(
 | 
			
		||||
                    "pybind11_object_dealloc(): Tried to deallocate unregistered instance!");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (instance->owned || v_h.holder_constructed()) {
 | 
			
		||||
                v_h.type->dealloc(v_h);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    // Deallocate the value/holder layout internals:
 | 
			
		||||
    instance->deallocate_layout();
 | 
			
		||||
 | 
			
		||||
    if (instance->weakrefs) {
 | 
			
		||||
        PyObject_ClearWeakRefs(self);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    PyObject **dict_ptr = _PyObject_GetDictPtr(self);
 | 
			
		||||
    if (dict_ptr) {
 | 
			
		||||
        Py_CLEAR(*dict_ptr);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (instance->has_patients) {
 | 
			
		||||
        clear_patients(self);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Instance destructor function for all pybind11 types. It calls `type_info.dealloc`
 | 
			
		||||
/// to destroy the C++ object itself, while the rest is Python bookkeeping.
 | 
			
		||||
extern "C" inline void pybind11_object_dealloc(PyObject *self) {
 | 
			
		||||
    auto *type = Py_TYPE(self);
 | 
			
		||||
 | 
			
		||||
    // If this is a GC tracked object, untrack it first
 | 
			
		||||
    // Note that the track call is implicitly done by the
 | 
			
		||||
    // default tp_alloc, which we never override.
 | 
			
		||||
    if (PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC) != 0) {
 | 
			
		||||
        PyObject_GC_UnTrack(self);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    clear_instance(self);
 | 
			
		||||
 | 
			
		||||
    type->tp_free(self);
 | 
			
		||||
 | 
			
		||||
#if PY_VERSION_HEX < 0x03080000
 | 
			
		||||
    // `type->tp_dealloc != pybind11_object_dealloc` means that we're being called
 | 
			
		||||
    // as part of a derived type's dealloc, in which case we're not allowed to decref
 | 
			
		||||
    // the type here. For cross-module compatibility, we shouldn't compare directly
 | 
			
		||||
    // with `pybind11_object_dealloc`, but with the common one stashed in internals.
 | 
			
		||||
    auto pybind11_object_type = (PyTypeObject *) get_internals().instance_base;
 | 
			
		||||
    if (type->tp_dealloc == pybind11_object_type->tp_dealloc)
 | 
			
		||||
        Py_DECREF(type);
 | 
			
		||||
#else
 | 
			
		||||
    // This was not needed before Python 3.8 (Python issue 35810)
 | 
			
		||||
    // https://github.com/pybind/pybind11/issues/1946
 | 
			
		||||
    Py_DECREF(type);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string error_string();
 | 
			
		||||
 | 
			
		||||
/** Create the type which can be used as a common base for all classes.  This is
 | 
			
		||||
    needed in order to satisfy Python's requirements for multiple inheritance.
 | 
			
		||||
    Return value: New reference. */
 | 
			
		||||
inline PyObject *make_object_base_type(PyTypeObject *metaclass) {
 | 
			
		||||
    constexpr auto *name = "pybind11_object";
 | 
			
		||||
    auto name_obj = reinterpret_steal<object>(PYBIND11_FROM_STRING(name));
 | 
			
		||||
 | 
			
		||||
    /* Danger zone: from now (and until PyType_Ready), make sure to
 | 
			
		||||
       issue no Python C API calls which could potentially invoke the
 | 
			
		||||
       garbage collector (the GC will call type_traverse(), which will in
 | 
			
		||||
       turn find the newly constructed type in an invalid state) */
 | 
			
		||||
    auto *heap_type = (PyHeapTypeObject *) metaclass->tp_alloc(metaclass, 0);
 | 
			
		||||
    if (!heap_type) {
 | 
			
		||||
        pybind11_fail("make_object_base_type(): error allocating type!");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    heap_type->ht_name = name_obj.inc_ref().ptr();
 | 
			
		||||
#ifdef PYBIND11_BUILTIN_QUALNAME
 | 
			
		||||
    heap_type->ht_qualname = name_obj.inc_ref().ptr();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    auto *type = &heap_type->ht_type;
 | 
			
		||||
    type->tp_name = name;
 | 
			
		||||
    type->tp_base = type_incref(&PyBaseObject_Type);
 | 
			
		||||
    type->tp_basicsize = static_cast<ssize_t>(sizeof(instance));
 | 
			
		||||
    type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;
 | 
			
		||||
 | 
			
		||||
    type->tp_new = pybind11_object_new;
 | 
			
		||||
    type->tp_init = pybind11_object_init;
 | 
			
		||||
    type->tp_dealloc = pybind11_object_dealloc;
 | 
			
		||||
 | 
			
		||||
    /* Support weak references (needed for the keep_alive feature) */
 | 
			
		||||
    type->tp_weaklistoffset = offsetof(instance, weakrefs);
 | 
			
		||||
 | 
			
		||||
    if (PyType_Ready(type) < 0) {
 | 
			
		||||
        pybind11_fail("PyType_Ready failed in make_object_base_type(): " + error_string());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setattr((PyObject *) type, "__module__", str("pybind11_builtins"));
 | 
			
		||||
    PYBIND11_SET_OLDPY_QUALNAME(type, name_obj);
 | 
			
		||||
 | 
			
		||||
    assert(!PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC));
 | 
			
		||||
    return (PyObject *) heap_type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// dynamic_attr: Allow the garbage collector to traverse the internal instance `__dict__`.
 | 
			
		||||
extern "C" inline int pybind11_traverse(PyObject *self, visitproc visit, void *arg) {
 | 
			
		||||
    PyObject *&dict = *_PyObject_GetDictPtr(self);
 | 
			
		||||
    Py_VISIT(dict);
 | 
			
		||||
// https://docs.python.org/3/c-api/typeobj.html#c.PyTypeObject.tp_traverse
 | 
			
		||||
#if PY_VERSION_HEX >= 0x03090000
 | 
			
		||||
    Py_VISIT(Py_TYPE(self));
 | 
			
		||||
#endif
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// dynamic_attr: Allow the GC to clear the dictionary.
 | 
			
		||||
extern "C" inline int pybind11_clear(PyObject *self) {
 | 
			
		||||
    PyObject *&dict = *_PyObject_GetDictPtr(self);
 | 
			
		||||
    Py_CLEAR(dict);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Give instances of this type a `__dict__` and opt into garbage collection.
 | 
			
		||||
inline void enable_dynamic_attributes(PyHeapTypeObject *heap_type) {
 | 
			
		||||
    auto *type = &heap_type->ht_type;
 | 
			
		||||
    type->tp_flags |= Py_TPFLAGS_HAVE_GC;
 | 
			
		||||
#if PY_VERSION_HEX < 0x030B0000
 | 
			
		||||
    type->tp_dictoffset = type->tp_basicsize;           // place dict at the end
 | 
			
		||||
    type->tp_basicsize += (ssize_t) sizeof(PyObject *); // and allocate enough space for it
 | 
			
		||||
#else
 | 
			
		||||
    type->tp_flags |= Py_TPFLAGS_MANAGED_DICT;
 | 
			
		||||
#endif
 | 
			
		||||
    type->tp_traverse = pybind11_traverse;
 | 
			
		||||
    type->tp_clear = pybind11_clear;
 | 
			
		||||
 | 
			
		||||
    static PyGetSetDef getset[] = {{
 | 
			
		||||
#if PY_VERSION_HEX < 0x03070000
 | 
			
		||||
                                       const_cast<char *>("__dict__"),
 | 
			
		||||
#else
 | 
			
		||||
                                       "__dict__",
 | 
			
		||||
#endif
 | 
			
		||||
                                       PyObject_GenericGetDict,
 | 
			
		||||
                                       PyObject_GenericSetDict,
 | 
			
		||||
                                       nullptr,
 | 
			
		||||
                                       nullptr},
 | 
			
		||||
                                   {nullptr, nullptr, nullptr, nullptr, nullptr}};
 | 
			
		||||
    type->tp_getset = getset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// buffer_protocol: Fill in the view as specified by flags.
 | 
			
		||||
extern "C" inline int pybind11_getbuffer(PyObject *obj, Py_buffer *view, int flags) {
 | 
			
		||||
    // Look for a `get_buffer` implementation in this type's info or any bases (following MRO).
 | 
			
		||||
    type_info *tinfo = nullptr;
 | 
			
		||||
    for (auto type : reinterpret_borrow<tuple>(Py_TYPE(obj)->tp_mro)) {
 | 
			
		||||
        tinfo = get_type_info((PyTypeObject *) type.ptr());
 | 
			
		||||
        if (tinfo && tinfo->get_buffer) {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (view == nullptr || !tinfo || !tinfo->get_buffer) {
 | 
			
		||||
        if (view) {
 | 
			
		||||
            view->obj = nullptr;
 | 
			
		||||
        }
 | 
			
		||||
        PyErr_SetString(PyExc_BufferError, "pybind11_getbuffer(): Internal error");
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
    std::memset(view, 0, sizeof(Py_buffer));
 | 
			
		||||
    buffer_info *info = tinfo->get_buffer(obj, tinfo->get_buffer_data);
 | 
			
		||||
    if ((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE && info->readonly) {
 | 
			
		||||
        delete info;
 | 
			
		||||
        // view->obj = nullptr;  // Was just memset to 0, so not necessary
 | 
			
		||||
        PyErr_SetString(PyExc_BufferError, "Writable buffer requested for readonly storage");
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
    view->obj = obj;
 | 
			
		||||
    view->ndim = 1;
 | 
			
		||||
    view->internal = info;
 | 
			
		||||
    view->buf = info->ptr;
 | 
			
		||||
    view->itemsize = info->itemsize;
 | 
			
		||||
    view->len = view->itemsize;
 | 
			
		||||
    for (auto s : info->shape) {
 | 
			
		||||
        view->len *= s;
 | 
			
		||||
    }
 | 
			
		||||
    view->readonly = static_cast<int>(info->readonly);
 | 
			
		||||
    if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
 | 
			
		||||
        view->format = const_cast<char *>(info->format.c_str());
 | 
			
		||||
    }
 | 
			
		||||
    if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
 | 
			
		||||
        view->ndim = (int) info->ndim;
 | 
			
		||||
        view->strides = info->strides.data();
 | 
			
		||||
        view->shape = info->shape.data();
 | 
			
		||||
    }
 | 
			
		||||
    Py_INCREF(view->obj);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// buffer_protocol: Release the resources of the buffer.
 | 
			
		||||
extern "C" inline void pybind11_releasebuffer(PyObject *, Py_buffer *view) {
 | 
			
		||||
    delete (buffer_info *) view->internal;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Give this type a buffer interface.
 | 
			
		||||
inline void enable_buffer_protocol(PyHeapTypeObject *heap_type) {
 | 
			
		||||
    heap_type->ht_type.tp_as_buffer = &heap_type->as_buffer;
 | 
			
		||||
 | 
			
		||||
    heap_type->as_buffer.bf_getbuffer = pybind11_getbuffer;
 | 
			
		||||
    heap_type->as_buffer.bf_releasebuffer = pybind11_releasebuffer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Create a brand new Python type according to the `type_record` specification.
 | 
			
		||||
    Return value: New reference. */
 | 
			
		||||
inline PyObject *make_new_python_type(const type_record &rec) {
 | 
			
		||||
    auto name = reinterpret_steal<object>(PYBIND11_FROM_STRING(rec.name));
 | 
			
		||||
 | 
			
		||||
    auto qualname = name;
 | 
			
		||||
    if (rec.scope && !PyModule_Check(rec.scope.ptr()) && hasattr(rec.scope, "__qualname__")) {
 | 
			
		||||
        qualname = reinterpret_steal<object>(
 | 
			
		||||
            PyUnicode_FromFormat("%U.%U", rec.scope.attr("__qualname__").ptr(), name.ptr()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    object module_;
 | 
			
		||||
    if (rec.scope) {
 | 
			
		||||
        if (hasattr(rec.scope, "__module__")) {
 | 
			
		||||
            module_ = rec.scope.attr("__module__");
 | 
			
		||||
        } else if (hasattr(rec.scope, "__name__")) {
 | 
			
		||||
            module_ = rec.scope.attr("__name__");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const auto *full_name = c_str(
 | 
			
		||||
#if !defined(PYPY_VERSION)
 | 
			
		||||
        module_ ? str(module_).cast<std::string>() + "." + rec.name :
 | 
			
		||||
#endif
 | 
			
		||||
                rec.name);
 | 
			
		||||
 | 
			
		||||
    char *tp_doc = nullptr;
 | 
			
		||||
    if (rec.doc && options::show_user_defined_docstrings()) {
 | 
			
		||||
        /* Allocate memory for docstring (using PyObject_MALLOC, since
 | 
			
		||||
           Python will free this later on) */
 | 
			
		||||
        size_t size = std::strlen(rec.doc) + 1;
 | 
			
		||||
        tp_doc = (char *) PyObject_MALLOC(size);
 | 
			
		||||
        std::memcpy((void *) tp_doc, rec.doc, size);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    auto &internals = get_internals();
 | 
			
		||||
    auto bases = tuple(rec.bases);
 | 
			
		||||
    auto *base = (bases.empty()) ? internals.instance_base : bases[0].ptr();
 | 
			
		||||
 | 
			
		||||
    /* Danger zone: from now (and until PyType_Ready), make sure to
 | 
			
		||||
       issue no Python C API calls which could potentially invoke the
 | 
			
		||||
       garbage collector (the GC will call type_traverse(), which will in
 | 
			
		||||
       turn find the newly constructed type in an invalid state) */
 | 
			
		||||
    auto *metaclass
 | 
			
		||||
        = rec.metaclass.ptr() ? (PyTypeObject *) rec.metaclass.ptr() : internals.default_metaclass;
 | 
			
		||||
 | 
			
		||||
    auto *heap_type = (PyHeapTypeObject *) metaclass->tp_alloc(metaclass, 0);
 | 
			
		||||
    if (!heap_type) {
 | 
			
		||||
        pybind11_fail(std::string(rec.name) + ": Unable to create type object!");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    heap_type->ht_name = name.release().ptr();
 | 
			
		||||
#ifdef PYBIND11_BUILTIN_QUALNAME
 | 
			
		||||
    heap_type->ht_qualname = qualname.inc_ref().ptr();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    auto *type = &heap_type->ht_type;
 | 
			
		||||
    type->tp_name = full_name;
 | 
			
		||||
    type->tp_doc = tp_doc;
 | 
			
		||||
    type->tp_base = type_incref((PyTypeObject *) base);
 | 
			
		||||
    type->tp_basicsize = static_cast<ssize_t>(sizeof(instance));
 | 
			
		||||
    if (!bases.empty()) {
 | 
			
		||||
        type->tp_bases = bases.release().ptr();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Don't inherit base __init__ */
 | 
			
		||||
    type->tp_init = pybind11_object_init;
 | 
			
		||||
 | 
			
		||||
    /* Supported protocols */
 | 
			
		||||
    type->tp_as_number = &heap_type->as_number;
 | 
			
		||||
    type->tp_as_sequence = &heap_type->as_sequence;
 | 
			
		||||
    type->tp_as_mapping = &heap_type->as_mapping;
 | 
			
		||||
    type->tp_as_async = &heap_type->as_async;
 | 
			
		||||
 | 
			
		||||
    /* Flags */
 | 
			
		||||
    type->tp_flags |= Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE;
 | 
			
		||||
    if (!rec.is_final) {
 | 
			
		||||
        type->tp_flags |= Py_TPFLAGS_BASETYPE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (rec.dynamic_attr) {
 | 
			
		||||
        enable_dynamic_attributes(heap_type);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (rec.buffer_protocol) {
 | 
			
		||||
        enable_buffer_protocol(heap_type);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (rec.custom_type_setup_callback) {
 | 
			
		||||
        rec.custom_type_setup_callback(heap_type);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (PyType_Ready(type) < 0) {
 | 
			
		||||
        pybind11_fail(std::string(rec.name) + ": PyType_Ready failed: " + error_string());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    assert(!rec.dynamic_attr || PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC));
 | 
			
		||||
 | 
			
		||||
    /* Register type with the parent scope */
 | 
			
		||||
    if (rec.scope) {
 | 
			
		||||
        setattr(rec.scope, rec.name, (PyObject *) type);
 | 
			
		||||
    } else {
 | 
			
		||||
        Py_INCREF(type); // Keep it alive forever (reference leak)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (module_) { // Needed by pydoc
 | 
			
		||||
        setattr((PyObject *) type, "__module__", module_);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    PYBIND11_SET_OLDPY_QUALNAME(type, qualname);
 | 
			
		||||
 | 
			
		||||
    return (PyObject *) type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_END(detail)
 | 
			
		||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
 | 
			
		||||
							
								
								
									
										1255
									
								
								3rdparty/pybind11/include/pybind11/detail/common.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1255
									
								
								3rdparty/pybind11/include/pybind11/detail/common.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										171
									
								
								3rdparty/pybind11/include/pybind11/detail/descr.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								3rdparty/pybind11/include/pybind11/detail/descr.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,171 @@
 | 
			
		||||
/*
 | 
			
		||||
    pybind11/detail/descr.h: Helper type for concatenating type signatures at compile time
 | 
			
		||||
 | 
			
		||||
    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
 | 
			
		||||
 | 
			
		||||
    All rights reserved. Use of this source code is governed by a
 | 
			
		||||
    BSD-style license that can be found in the LICENSE file.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "common.h"
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(detail)
 | 
			
		||||
 | 
			
		||||
#if !defined(_MSC_VER)
 | 
			
		||||
#    define PYBIND11_DESCR_CONSTEXPR static constexpr
 | 
			
		||||
#else
 | 
			
		||||
#    define PYBIND11_DESCR_CONSTEXPR const
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Concatenate type signatures at compile time */
 | 
			
		||||
template <size_t N, typename... Ts>
 | 
			
		||||
struct descr {
 | 
			
		||||
    char text[N + 1]{'\0'};
 | 
			
		||||
 | 
			
		||||
    constexpr descr() = default;
 | 
			
		||||
    // NOLINTNEXTLINE(google-explicit-constructor)
 | 
			
		||||
    constexpr descr(char const (&s)[N + 1]) : descr(s, make_index_sequence<N>()) {}
 | 
			
		||||
 | 
			
		||||
    template <size_t... Is>
 | 
			
		||||
    constexpr descr(char const (&s)[N + 1], index_sequence<Is...>) : text{s[Is]..., '\0'} {}
 | 
			
		||||
 | 
			
		||||
    template <typename... Chars>
 | 
			
		||||
    // NOLINTNEXTLINE(google-explicit-constructor)
 | 
			
		||||
    constexpr descr(char c, Chars... cs) : text{c, static_cast<char>(cs)..., '\0'} {}
 | 
			
		||||
 | 
			
		||||
    static constexpr std::array<const std::type_info *, sizeof...(Ts) + 1> types() {
 | 
			
		||||
        return {{&typeid(Ts)..., nullptr}};
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <size_t N1, size_t N2, typename... Ts1, typename... Ts2, size_t... Is1, size_t... Is2>
 | 
			
		||||
constexpr descr<N1 + N2, Ts1..., Ts2...> plus_impl(const descr<N1, Ts1...> &a,
 | 
			
		||||
                                                   const descr<N2, Ts2...> &b,
 | 
			
		||||
                                                   index_sequence<Is1...>,
 | 
			
		||||
                                                   index_sequence<Is2...>) {
 | 
			
		||||
    PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(b);
 | 
			
		||||
    return {a.text[Is1]..., b.text[Is2]...};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <size_t N1, size_t N2, typename... Ts1, typename... Ts2>
 | 
			
		||||
constexpr descr<N1 + N2, Ts1..., Ts2...> operator+(const descr<N1, Ts1...> &a,
 | 
			
		||||
                                                   const descr<N2, Ts2...> &b) {
 | 
			
		||||
    return plus_impl(a, b, make_index_sequence<N1>(), make_index_sequence<N2>());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <size_t N>
 | 
			
		||||
constexpr descr<N - 1> const_name(char const (&text)[N]) {
 | 
			
		||||
    return descr<N - 1>(text);
 | 
			
		||||
}
 | 
			
		||||
constexpr descr<0> const_name(char const (&)[1]) { return {}; }
 | 
			
		||||
 | 
			
		||||
template <size_t Rem, size_t... Digits>
 | 
			
		||||
struct int_to_str : int_to_str<Rem / 10, Rem % 10, Digits...> {};
 | 
			
		||||
template <size_t... Digits>
 | 
			
		||||
struct int_to_str<0, Digits...> {
 | 
			
		||||
    // WARNING: This only works with C++17 or higher.
 | 
			
		||||
    static constexpr auto digits = descr<sizeof...(Digits)>(('0' + Digits)...);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Ternary description (like std::conditional)
 | 
			
		||||
template <bool B, size_t N1, size_t N2>
 | 
			
		||||
constexpr enable_if_t<B, descr<N1 - 1>> const_name(char const (&text1)[N1], char const (&)[N2]) {
 | 
			
		||||
    return const_name(text1);
 | 
			
		||||
}
 | 
			
		||||
template <bool B, size_t N1, size_t N2>
 | 
			
		||||
constexpr enable_if_t<!B, descr<N2 - 1>> const_name(char const (&)[N1], char const (&text2)[N2]) {
 | 
			
		||||
    return const_name(text2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <bool B, typename T1, typename T2>
 | 
			
		||||
constexpr enable_if_t<B, T1> const_name(const T1 &d, const T2 &) {
 | 
			
		||||
    return d;
 | 
			
		||||
}
 | 
			
		||||
template <bool B, typename T1, typename T2>
 | 
			
		||||
constexpr enable_if_t<!B, T2> const_name(const T1 &, const T2 &d) {
 | 
			
		||||
    return d;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <size_t Size>
 | 
			
		||||
auto constexpr const_name() -> remove_cv_t<decltype(int_to_str<Size / 10, Size % 10>::digits)> {
 | 
			
		||||
    return int_to_str<Size / 10, Size % 10>::digits;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Type>
 | 
			
		||||
constexpr descr<1, Type> const_name() {
 | 
			
		||||
    return {'%'};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// If "_" is defined as a macro, py::detail::_ cannot be provided.
 | 
			
		||||
// It is therefore best to use py::detail::const_name universally.
 | 
			
		||||
// This block is for backward compatibility only.
 | 
			
		||||
// (The const_name code is repeated to avoid introducing a "_" #define ourselves.)
 | 
			
		||||
#ifndef _
 | 
			
		||||
#    define PYBIND11_DETAIL_UNDERSCORE_BACKWARD_COMPATIBILITY
 | 
			
		||||
template <size_t N>
 | 
			
		||||
constexpr descr<N - 1> _(char const (&text)[N]) {
 | 
			
		||||
    return const_name<N>(text);
 | 
			
		||||
}
 | 
			
		||||
template <bool B, size_t N1, size_t N2>
 | 
			
		||||
constexpr enable_if_t<B, descr<N1 - 1>> _(char const (&text1)[N1], char const (&text2)[N2]) {
 | 
			
		||||
    return const_name<B, N1, N2>(text1, text2);
 | 
			
		||||
}
 | 
			
		||||
template <bool B, size_t N1, size_t N2>
 | 
			
		||||
constexpr enable_if_t<!B, descr<N2 - 1>> _(char const (&text1)[N1], char const (&text2)[N2]) {
 | 
			
		||||
    return const_name<B, N1, N2>(text1, text2);
 | 
			
		||||
}
 | 
			
		||||
template <bool B, typename T1, typename T2>
 | 
			
		||||
constexpr enable_if_t<B, T1> _(const T1 &d1, const T2 &d2) {
 | 
			
		||||
    return const_name<B, T1, T2>(d1, d2);
 | 
			
		||||
}
 | 
			
		||||
template <bool B, typename T1, typename T2>
 | 
			
		||||
constexpr enable_if_t<!B, T2> _(const T1 &d1, const T2 &d2) {
 | 
			
		||||
    return const_name<B, T1, T2>(d1, d2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <size_t Size>
 | 
			
		||||
auto constexpr _() -> remove_cv_t<decltype(int_to_str<Size / 10, Size % 10>::digits)> {
 | 
			
		||||
    return const_name<Size>();
 | 
			
		||||
}
 | 
			
		||||
template <typename Type>
 | 
			
		||||
constexpr descr<1, Type> _() {
 | 
			
		||||
    return const_name<Type>();
 | 
			
		||||
}
 | 
			
		||||
#endif // #ifndef _
 | 
			
		||||
 | 
			
		||||
constexpr descr<0> concat() { return {}; }
 | 
			
		||||
 | 
			
		||||
template <size_t N, typename... Ts>
 | 
			
		||||
constexpr descr<N, Ts...> concat(const descr<N, Ts...> &descr) {
 | 
			
		||||
    return descr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef __cpp_fold_expressions
 | 
			
		||||
template <size_t N1, size_t N2, typename... Ts1, typename... Ts2>
 | 
			
		||||
constexpr descr<N1 + N2 + 2, Ts1..., Ts2...> operator,(const descr<N1, Ts1...> &a,
 | 
			
		||||
                                                       const descr<N2, Ts2...> &b) {
 | 
			
		||||
    return a + const_name(", ") + b;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <size_t N, typename... Ts, typename... Args>
 | 
			
		||||
constexpr auto concat(const descr<N, Ts...> &d, const Args &...args) {
 | 
			
		||||
    return (d, ..., args);
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
template <size_t N, typename... Ts, typename... Args>
 | 
			
		||||
constexpr auto concat(const descr<N, Ts...> &d, const Args &...args)
 | 
			
		||||
    -> decltype(std::declval<descr<N + 2, Ts...>>() + concat(args...)) {
 | 
			
		||||
    return d + const_name(", ") + concat(args...);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
template <size_t N, typename... Ts>
 | 
			
		||||
constexpr descr<N + 2, Ts...> type_descr(const descr<N, Ts...> &descr) {
 | 
			
		||||
    return const_name("{") + descr + const_name("}");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_END(detail)
 | 
			
		||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
 | 
			
		||||
							
								
								
									
										434
									
								
								3rdparty/pybind11/include/pybind11/detail/init.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										434
									
								
								3rdparty/pybind11/include/pybind11/detail/init.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,434 @@
 | 
			
		||||
/*
 | 
			
		||||
    pybind11/detail/init.h: init factory function implementation and support code.
 | 
			
		||||
 | 
			
		||||
    Copyright (c) 2017 Jason Rhinelander <jason@imaginary.ca>
 | 
			
		||||
 | 
			
		||||
    All rights reserved. Use of this source code is governed by a
 | 
			
		||||
    BSD-style license that can be found in the LICENSE file.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "class.h"
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
 | 
			
		||||
 | 
			
		||||
PYBIND11_WARNING_DISABLE_MSVC(4127)
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(detail)
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
class type_caster<value_and_holder> {
 | 
			
		||||
public:
 | 
			
		||||
    bool load(handle h, bool) {
 | 
			
		||||
        value = reinterpret_cast<value_and_holder *>(h.ptr());
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <typename>
 | 
			
		||||
    using cast_op_type = value_and_holder &;
 | 
			
		||||
    explicit operator value_and_holder &() { return *value; }
 | 
			
		||||
    static constexpr auto name = const_name<value_and_holder>();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    value_and_holder *value = nullptr;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(initimpl)
 | 
			
		||||
 | 
			
		||||
inline void no_nullptr(void *ptr) {
 | 
			
		||||
    if (!ptr) {
 | 
			
		||||
        throw type_error("pybind11::init(): factory function returned nullptr");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Implementing functions for all forms of py::init<...> and py::init(...)
 | 
			
		||||
template <typename Class>
 | 
			
		||||
using Cpp = typename Class::type;
 | 
			
		||||
template <typename Class>
 | 
			
		||||
using Alias = typename Class::type_alias;
 | 
			
		||||
template <typename Class>
 | 
			
		||||
using Holder = typename Class::holder_type;
 | 
			
		||||
 | 
			
		||||
template <typename Class>
 | 
			
		||||
using is_alias_constructible = std::is_constructible<Alias<Class>, Cpp<Class> &&>;
 | 
			
		||||
 | 
			
		||||
// Takes a Cpp pointer and returns true if it actually is a polymorphic Alias instance.
 | 
			
		||||
template <typename Class, enable_if_t<Class::has_alias, int> = 0>
 | 
			
		||||
bool is_alias(Cpp<Class> *ptr) {
 | 
			
		||||
    return dynamic_cast<Alias<Class> *>(ptr) != nullptr;
 | 
			
		||||
}
 | 
			
		||||
// Failing fallback version of the above for a no-alias class (always returns false)
 | 
			
		||||
template <typename /*Class*/>
 | 
			
		||||
constexpr bool is_alias(void *) {
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Constructs and returns a new object; if the given arguments don't map to a constructor, we fall
 | 
			
		||||
// back to brace aggregate initiailization so that for aggregate initialization can be used with
 | 
			
		||||
// py::init, e.g.  `py::init<int, int>` to initialize a `struct T { int a; int b; }`.  For
 | 
			
		||||
// non-aggregate types, we need to use an ordinary T(...) constructor (invoking as `T{...}` usually
 | 
			
		||||
// works, but will not do the expected thing when `T` has an `initializer_list<T>` constructor).
 | 
			
		||||
template <typename Class,
 | 
			
		||||
          typename... Args,
 | 
			
		||||
          detail::enable_if_t<std::is_constructible<Class, Args...>::value, int> = 0>
 | 
			
		||||
inline Class *construct_or_initialize(Args &&...args) {
 | 
			
		||||
    return new Class(std::forward<Args>(args)...);
 | 
			
		||||
}
 | 
			
		||||
template <typename Class,
 | 
			
		||||
          typename... Args,
 | 
			
		||||
          detail::enable_if_t<!std::is_constructible<Class, Args...>::value, int> = 0>
 | 
			
		||||
inline Class *construct_or_initialize(Args &&...args) {
 | 
			
		||||
    return new Class{std::forward<Args>(args)...};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Attempts to constructs an alias using a `Alias(Cpp &&)` constructor.  This allows types with
 | 
			
		||||
// an alias to provide only a single Cpp factory function as long as the Alias can be
 | 
			
		||||
// constructed from an rvalue reference of the base Cpp type.  This means that Alias classes
 | 
			
		||||
// can, when appropriate, simply define a `Alias(Cpp &&)` constructor rather than needing to
 | 
			
		||||
// inherit all the base class constructors.
 | 
			
		||||
template <typename Class>
 | 
			
		||||
void construct_alias_from_cpp(std::true_type /*is_alias_constructible*/,
 | 
			
		||||
                              value_and_holder &v_h,
 | 
			
		||||
                              Cpp<Class> &&base) {
 | 
			
		||||
    v_h.value_ptr() = new Alias<Class>(std::move(base));
 | 
			
		||||
}
 | 
			
		||||
template <typename Class>
 | 
			
		||||
[[noreturn]] void construct_alias_from_cpp(std::false_type /*!is_alias_constructible*/,
 | 
			
		||||
                                           value_and_holder &,
 | 
			
		||||
                                           Cpp<Class> &&) {
 | 
			
		||||
    throw type_error("pybind11::init(): unable to convert returned instance to required "
 | 
			
		||||
                     "alias class: no `Alias<Class>(Class &&)` constructor available");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Error-generating fallback for factories that don't match one of the below construction
 | 
			
		||||
// mechanisms.
 | 
			
		||||
template <typename Class>
 | 
			
		||||
void construct(...) {
 | 
			
		||||
    static_assert(!std::is_same<Class, Class>::value /* always false */,
 | 
			
		||||
                  "pybind11::init(): init function must return a compatible pointer, "
 | 
			
		||||
                  "holder, or value");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Pointer return v1: the factory function returns a class pointer for a registered class.
 | 
			
		||||
// If we don't need an alias (because this class doesn't have one, or because the final type is
 | 
			
		||||
// inherited on the Python side) we can simply take over ownership.  Otherwise we need to try to
 | 
			
		||||
// construct an Alias from the returned base instance.
 | 
			
		||||
template <typename Class>
 | 
			
		||||
void construct(value_and_holder &v_h, Cpp<Class> *ptr, bool need_alias) {
 | 
			
		||||
    PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
 | 
			
		||||
    no_nullptr(ptr);
 | 
			
		||||
    if (Class::has_alias && need_alias && !is_alias<Class>(ptr)) {
 | 
			
		||||
        // We're going to try to construct an alias by moving the cpp type.  Whether or not
 | 
			
		||||
        // that succeeds, we still need to destroy the original cpp pointer (either the
 | 
			
		||||
        // moved away leftover, if the alias construction works, or the value itself if we
 | 
			
		||||
        // throw an error), but we can't just call `delete ptr`: it might have a special
 | 
			
		||||
        // deleter, or might be shared_from_this.  So we construct a holder around it as if
 | 
			
		||||
        // it was a normal instance, then steal the holder away into a local variable; thus
 | 
			
		||||
        // the holder and destruction happens when we leave the C++ scope, and the holder
 | 
			
		||||
        // class gets to handle the destruction however it likes.
 | 
			
		||||
        v_h.value_ptr() = ptr;
 | 
			
		||||
        v_h.set_instance_registered(true);          // To prevent init_instance from registering it
 | 
			
		||||
        v_h.type->init_instance(v_h.inst, nullptr); // Set up the holder
 | 
			
		||||
        Holder<Class> temp_holder(std::move(v_h.holder<Holder<Class>>())); // Steal the holder
 | 
			
		||||
        v_h.type->dealloc(v_h); // Destroys the moved-out holder remains, resets value ptr to null
 | 
			
		||||
        v_h.set_instance_registered(false);
 | 
			
		||||
 | 
			
		||||
        construct_alias_from_cpp<Class>(is_alias_constructible<Class>{}, v_h, std::move(*ptr));
 | 
			
		||||
    } else {
 | 
			
		||||
        // Otherwise the type isn't inherited, so we don't need an Alias
 | 
			
		||||
        v_h.value_ptr() = ptr;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Pointer return v2: a factory that always returns an alias instance ptr.  We simply take over
 | 
			
		||||
// ownership of the pointer.
 | 
			
		||||
template <typename Class, enable_if_t<Class::has_alias, int> = 0>
 | 
			
		||||
void construct(value_and_holder &v_h, Alias<Class> *alias_ptr, bool) {
 | 
			
		||||
    no_nullptr(alias_ptr);
 | 
			
		||||
    v_h.value_ptr() = static_cast<Cpp<Class> *>(alias_ptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Holder return: copy its pointer, and move or copy the returned holder into the new instance's
 | 
			
		||||
// holder.  This also handles types like std::shared_ptr<T> and std::unique_ptr<T> where T is a
 | 
			
		||||
// derived type (through those holder's implicit conversion from derived class holder
 | 
			
		||||
// constructors).
 | 
			
		||||
template <typename Class>
 | 
			
		||||
void construct(value_and_holder &v_h, Holder<Class> holder, bool need_alias) {
 | 
			
		||||
    PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
 | 
			
		||||
    auto *ptr = holder_helper<Holder<Class>>::get(holder);
 | 
			
		||||
    no_nullptr(ptr);
 | 
			
		||||
    // If we need an alias, check that the held pointer is actually an alias instance
 | 
			
		||||
    if (Class::has_alias && need_alias && !is_alias<Class>(ptr)) {
 | 
			
		||||
        throw type_error("pybind11::init(): construction failed: returned holder-wrapped instance "
 | 
			
		||||
                         "is not an alias instance");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    v_h.value_ptr() = ptr;
 | 
			
		||||
    v_h.type->init_instance(v_h.inst, &holder);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// return-by-value version 1: returning a cpp class by value.  If the class has an alias and an
 | 
			
		||||
// alias is required the alias must have an `Alias(Cpp &&)` constructor so that we can construct
 | 
			
		||||
// the alias from the base when needed (i.e. because of Python-side inheritance).  When we don't
 | 
			
		||||
// need it, we simply move-construct the cpp value into a new instance.
 | 
			
		||||
template <typename Class>
 | 
			
		||||
void construct(value_and_holder &v_h, Cpp<Class> &&result, bool need_alias) {
 | 
			
		||||
    PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
 | 
			
		||||
    static_assert(is_move_constructible<Cpp<Class>>::value,
 | 
			
		||||
                  "pybind11::init() return-by-value factory function requires a movable class");
 | 
			
		||||
    if (Class::has_alias && need_alias) {
 | 
			
		||||
        construct_alias_from_cpp<Class>(is_alias_constructible<Class>{}, v_h, std::move(result));
 | 
			
		||||
    } else {
 | 
			
		||||
        v_h.value_ptr() = new Cpp<Class>(std::move(result));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// return-by-value version 2: returning a value of the alias type itself.  We move-construct an
 | 
			
		||||
// Alias instance (even if no the python-side inheritance is involved).  The is intended for
 | 
			
		||||
// cases where Alias initialization is always desired.
 | 
			
		||||
template <typename Class>
 | 
			
		||||
void construct(value_and_holder &v_h, Alias<Class> &&result, bool) {
 | 
			
		||||
    static_assert(
 | 
			
		||||
        is_move_constructible<Alias<Class>>::value,
 | 
			
		||||
        "pybind11::init() return-by-alias-value factory function requires a movable alias class");
 | 
			
		||||
    v_h.value_ptr() = new Alias<Class>(std::move(result));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Implementing class for py::init<...>()
 | 
			
		||||
template <typename... Args>
 | 
			
		||||
struct constructor {
 | 
			
		||||
    template <typename Class, typename... Extra, enable_if_t<!Class::has_alias, int> = 0>
 | 
			
		||||
    static void execute(Class &cl, const Extra &...extra) {
 | 
			
		||||
        cl.def(
 | 
			
		||||
            "__init__",
 | 
			
		||||
            [](value_and_holder &v_h, Args... args) {
 | 
			
		||||
                v_h.value_ptr() = construct_or_initialize<Cpp<Class>>(std::forward<Args>(args)...);
 | 
			
		||||
            },
 | 
			
		||||
            is_new_style_constructor(),
 | 
			
		||||
            extra...);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <
 | 
			
		||||
        typename Class,
 | 
			
		||||
        typename... Extra,
 | 
			
		||||
        enable_if_t<Class::has_alias && std::is_constructible<Cpp<Class>, Args...>::value, int>
 | 
			
		||||
        = 0>
 | 
			
		||||
    static void execute(Class &cl, const Extra &...extra) {
 | 
			
		||||
        cl.def(
 | 
			
		||||
            "__init__",
 | 
			
		||||
            [](value_and_holder &v_h, Args... args) {
 | 
			
		||||
                if (Py_TYPE(v_h.inst) == v_h.type->type) {
 | 
			
		||||
                    v_h.value_ptr()
 | 
			
		||||
                        = construct_or_initialize<Cpp<Class>>(std::forward<Args>(args)...);
 | 
			
		||||
                } else {
 | 
			
		||||
                    v_h.value_ptr()
 | 
			
		||||
                        = construct_or_initialize<Alias<Class>>(std::forward<Args>(args)...);
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            is_new_style_constructor(),
 | 
			
		||||
            extra...);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <
 | 
			
		||||
        typename Class,
 | 
			
		||||
        typename... Extra,
 | 
			
		||||
        enable_if_t<Class::has_alias && !std::is_constructible<Cpp<Class>, Args...>::value, int>
 | 
			
		||||
        = 0>
 | 
			
		||||
    static void execute(Class &cl, const Extra &...extra) {
 | 
			
		||||
        cl.def(
 | 
			
		||||
            "__init__",
 | 
			
		||||
            [](value_and_holder &v_h, Args... args) {
 | 
			
		||||
                v_h.value_ptr()
 | 
			
		||||
                    = construct_or_initialize<Alias<Class>>(std::forward<Args>(args)...);
 | 
			
		||||
            },
 | 
			
		||||
            is_new_style_constructor(),
 | 
			
		||||
            extra...);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Implementing class for py::init_alias<...>()
 | 
			
		||||
template <typename... Args>
 | 
			
		||||
struct alias_constructor {
 | 
			
		||||
    template <
 | 
			
		||||
        typename Class,
 | 
			
		||||
        typename... Extra,
 | 
			
		||||
        enable_if_t<Class::has_alias && std::is_constructible<Alias<Class>, Args...>::value, int>
 | 
			
		||||
        = 0>
 | 
			
		||||
    static void execute(Class &cl, const Extra &...extra) {
 | 
			
		||||
        cl.def(
 | 
			
		||||
            "__init__",
 | 
			
		||||
            [](value_and_holder &v_h, Args... args) {
 | 
			
		||||
                v_h.value_ptr()
 | 
			
		||||
                    = construct_or_initialize<Alias<Class>>(std::forward<Args>(args)...);
 | 
			
		||||
            },
 | 
			
		||||
            is_new_style_constructor(),
 | 
			
		||||
            extra...);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Implementation class for py::init(Func) and py::init(Func, AliasFunc)
 | 
			
		||||
template <typename CFunc,
 | 
			
		||||
          typename AFunc = void_type (*)(),
 | 
			
		||||
          typename = function_signature_t<CFunc>,
 | 
			
		||||
          typename = function_signature_t<AFunc>>
 | 
			
		||||
struct factory;
 | 
			
		||||
 | 
			
		||||
// Specialization for py::init(Func)
 | 
			
		||||
template <typename Func, typename Return, typename... Args>
 | 
			
		||||
struct factory<Func, void_type (*)(), Return(Args...)> {
 | 
			
		||||
    remove_reference_t<Func> class_factory;
 | 
			
		||||
 | 
			
		||||
    // NOLINTNEXTLINE(google-explicit-constructor)
 | 
			
		||||
    factory(Func &&f) : class_factory(std::forward<Func>(f)) {}
 | 
			
		||||
 | 
			
		||||
    // The given class either has no alias or has no separate alias factory;
 | 
			
		||||
    // this always constructs the class itself.  If the class is registered with an alias
 | 
			
		||||
    // type and an alias instance is needed (i.e. because the final type is a Python class
 | 
			
		||||
    // inheriting from the C++ type) the returned value needs to either already be an alias
 | 
			
		||||
    // instance, or the alias needs to be constructible from a `Class &&` argument.
 | 
			
		||||
    template <typename Class, typename... Extra>
 | 
			
		||||
    void execute(Class &cl, const Extra &...extra) && {
 | 
			
		||||
#if defined(PYBIND11_CPP14)
 | 
			
		||||
        cl.def(
 | 
			
		||||
            "__init__",
 | 
			
		||||
            [func = std::move(class_factory)]
 | 
			
		||||
#else
 | 
			
		||||
        auto &func = class_factory;
 | 
			
		||||
        cl.def(
 | 
			
		||||
            "__init__",
 | 
			
		||||
            [func]
 | 
			
		||||
#endif
 | 
			
		||||
            (value_and_holder &v_h, Args... args) {
 | 
			
		||||
                construct<Class>(
 | 
			
		||||
                    v_h, func(std::forward<Args>(args)...), Py_TYPE(v_h.inst) != v_h.type->type);
 | 
			
		||||
            },
 | 
			
		||||
            is_new_style_constructor(),
 | 
			
		||||
            extra...);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Specialization for py::init(Func, AliasFunc)
 | 
			
		||||
template <typename CFunc,
 | 
			
		||||
          typename AFunc,
 | 
			
		||||
          typename CReturn,
 | 
			
		||||
          typename... CArgs,
 | 
			
		||||
          typename AReturn,
 | 
			
		||||
          typename... AArgs>
 | 
			
		||||
struct factory<CFunc, AFunc, CReturn(CArgs...), AReturn(AArgs...)> {
 | 
			
		||||
    static_assert(sizeof...(CArgs) == sizeof...(AArgs),
 | 
			
		||||
                  "pybind11::init(class_factory, alias_factory): class and alias factories "
 | 
			
		||||
                  "must have identical argument signatures");
 | 
			
		||||
    static_assert(all_of<std::is_same<CArgs, AArgs>...>::value,
 | 
			
		||||
                  "pybind11::init(class_factory, alias_factory): class and alias factories "
 | 
			
		||||
                  "must have identical argument signatures");
 | 
			
		||||
 | 
			
		||||
    remove_reference_t<CFunc> class_factory;
 | 
			
		||||
    remove_reference_t<AFunc> alias_factory;
 | 
			
		||||
 | 
			
		||||
    factory(CFunc &&c, AFunc &&a)
 | 
			
		||||
        : class_factory(std::forward<CFunc>(c)), alias_factory(std::forward<AFunc>(a)) {}
 | 
			
		||||
 | 
			
		||||
    // The class factory is called when the `self` type passed to `__init__` is the direct
 | 
			
		||||
    // class (i.e. not inherited), the alias factory when `self` is a Python-side subtype.
 | 
			
		||||
    template <typename Class, typename... Extra>
 | 
			
		||||
    void execute(Class &cl, const Extra &...extra) && {
 | 
			
		||||
        static_assert(Class::has_alias,
 | 
			
		||||
                      "The two-argument version of `py::init()` can "
 | 
			
		||||
                      "only be used if the class has an alias");
 | 
			
		||||
#if defined(PYBIND11_CPP14)
 | 
			
		||||
        cl.def(
 | 
			
		||||
            "__init__",
 | 
			
		||||
            [class_func = std::move(class_factory), alias_func = std::move(alias_factory)]
 | 
			
		||||
#else
 | 
			
		||||
        auto &class_func = class_factory;
 | 
			
		||||
        auto &alias_func = alias_factory;
 | 
			
		||||
        cl.def(
 | 
			
		||||
            "__init__",
 | 
			
		||||
            [class_func, alias_func]
 | 
			
		||||
#endif
 | 
			
		||||
            (value_and_holder &v_h, CArgs... args) {
 | 
			
		||||
                if (Py_TYPE(v_h.inst) == v_h.type->type) {
 | 
			
		||||
                    // If the instance type equals the registered type we don't have inheritance,
 | 
			
		||||
                    // so don't need the alias and can construct using the class function:
 | 
			
		||||
                    construct<Class>(v_h, class_func(std::forward<CArgs>(args)...), false);
 | 
			
		||||
                } else {
 | 
			
		||||
                    construct<Class>(v_h, alias_func(std::forward<CArgs>(args)...), true);
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            is_new_style_constructor(),
 | 
			
		||||
            extra...);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Set just the C++ state. Same as `__init__`.
 | 
			
		||||
template <typename Class, typename T>
 | 
			
		||||
void setstate(value_and_holder &v_h, T &&result, bool need_alias) {
 | 
			
		||||
    construct<Class>(v_h, std::forward<T>(result), need_alias);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Set both the C++ and Python states
 | 
			
		||||
template <typename Class,
 | 
			
		||||
          typename T,
 | 
			
		||||
          typename O,
 | 
			
		||||
          enable_if_t<std::is_convertible<O, handle>::value, int> = 0>
 | 
			
		||||
void setstate(value_and_holder &v_h, std::pair<T, O> &&result, bool need_alias) {
 | 
			
		||||
    construct<Class>(v_h, std::move(result.first), need_alias);
 | 
			
		||||
    auto d = handle(result.second);
 | 
			
		||||
    if (PyDict_Check(d.ptr()) && PyDict_Size(d.ptr()) == 0) {
 | 
			
		||||
        // Skipping setattr below, to not force use of py::dynamic_attr() for Class unnecessarily.
 | 
			
		||||
        // See PR #2972 for details.
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    setattr((PyObject *) v_h.inst, "__dict__", d);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Implementation for py::pickle(GetState, SetState)
 | 
			
		||||
template <typename Get,
 | 
			
		||||
          typename Set,
 | 
			
		||||
          typename = function_signature_t<Get>,
 | 
			
		||||
          typename = function_signature_t<Set>>
 | 
			
		||||
struct pickle_factory;
 | 
			
		||||
 | 
			
		||||
template <typename Get,
 | 
			
		||||
          typename Set,
 | 
			
		||||
          typename RetState,
 | 
			
		||||
          typename Self,
 | 
			
		||||
          typename NewInstance,
 | 
			
		||||
          typename ArgState>
 | 
			
		||||
struct pickle_factory<Get, Set, RetState(Self), NewInstance(ArgState)> {
 | 
			
		||||
    static_assert(std::is_same<intrinsic_t<RetState>, intrinsic_t<ArgState>>::value,
 | 
			
		||||
                  "The type returned by `__getstate__` must be the same "
 | 
			
		||||
                  "as the argument accepted by `__setstate__`");
 | 
			
		||||
 | 
			
		||||
    remove_reference_t<Get> get;
 | 
			
		||||
    remove_reference_t<Set> set;
 | 
			
		||||
 | 
			
		||||
    pickle_factory(Get get, Set set) : get(std::forward<Get>(get)), set(std::forward<Set>(set)) {}
 | 
			
		||||
 | 
			
		||||
    template <typename Class, typename... Extra>
 | 
			
		||||
    void execute(Class &cl, const Extra &...extra) && {
 | 
			
		||||
        cl.def("__getstate__", std::move(get));
 | 
			
		||||
 | 
			
		||||
#if defined(PYBIND11_CPP14)
 | 
			
		||||
        cl.def(
 | 
			
		||||
            "__setstate__",
 | 
			
		||||
            [func = std::move(set)]
 | 
			
		||||
#else
 | 
			
		||||
        auto &func = set;
 | 
			
		||||
        cl.def(
 | 
			
		||||
            "__setstate__",
 | 
			
		||||
            [func]
 | 
			
		||||
#endif
 | 
			
		||||
            (value_and_holder &v_h, ArgState state) {
 | 
			
		||||
                setstate<Class>(
 | 
			
		||||
                    v_h, func(std::forward<ArgState>(state)), Py_TYPE(v_h.inst) != v_h.type->type);
 | 
			
		||||
            },
 | 
			
		||||
            is_new_style_constructor(),
 | 
			
		||||
            extra...);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_END(initimpl)
 | 
			
		||||
PYBIND11_NAMESPACE_END(detail)
 | 
			
		||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
 | 
			
		||||
							
								
								
									
										656
									
								
								3rdparty/pybind11/include/pybind11/detail/internals.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										656
									
								
								3rdparty/pybind11/include/pybind11/detail/internals.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,656 @@
 | 
			
		||||
/*
 | 
			
		||||
    pybind11/detail/internals.h: Internal data structure and related functions
 | 
			
		||||
 | 
			
		||||
    Copyright (c) 2017 Wenzel Jakob <wenzel.jakob@epfl.ch>
 | 
			
		||||
 | 
			
		||||
    All rights reserved. Use of this source code is governed by a
 | 
			
		||||
    BSD-style license that can be found in the LICENSE file.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "common.h"
 | 
			
		||||
 | 
			
		||||
#if defined(WITH_THREAD) && defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)
 | 
			
		||||
#    include "../gil.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "../pytypes.h"
 | 
			
		||||
 | 
			
		||||
#include <exception>
 | 
			
		||||
 | 
			
		||||
/// Tracks the `internals` and `type_info` ABI version independent of the main library version.
 | 
			
		||||
///
 | 
			
		||||
/// Some portions of the code use an ABI that is conditional depending on this
 | 
			
		||||
/// version number.  That allows ABI-breaking changes to be "pre-implemented".
 | 
			
		||||
/// Once the default version number is incremented, the conditional logic that
 | 
			
		||||
/// no longer applies can be removed.  Additionally, users that need not
 | 
			
		||||
/// maintain ABI compatibility can increase the version number in order to take
 | 
			
		||||
/// advantage of any functionality/efficiency improvements that depend on the
 | 
			
		||||
/// newer ABI.
 | 
			
		||||
///
 | 
			
		||||
/// WARNING: If you choose to manually increase the ABI version, note that
 | 
			
		||||
/// pybind11 may not be tested as thoroughly with a non-default ABI version, and
 | 
			
		||||
/// further ABI-incompatible changes may be made before the ABI is officially
 | 
			
		||||
/// changed to the new version.
 | 
			
		||||
#ifndef PYBIND11_INTERNALS_VERSION
 | 
			
		||||
#    if PY_VERSION_HEX >= 0x030C0000
 | 
			
		||||
// Version bump for Python 3.12+, before first 3.12 beta release.
 | 
			
		||||
#        define PYBIND11_INTERNALS_VERSION 5
 | 
			
		||||
#    else
 | 
			
		||||
#        define PYBIND11_INTERNALS_VERSION 4
 | 
			
		||||
#    endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// This requirement is mainly to reduce the support burden (see PR #4570).
 | 
			
		||||
static_assert(PY_VERSION_HEX < 0x030C0000 || PYBIND11_INTERNALS_VERSION >= 5,
 | 
			
		||||
              "pybind11 ABI version 5 is the minimum for Python 3.12+");
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
 | 
			
		||||
 | 
			
		||||
using ExceptionTranslator = void (*)(std::exception_ptr);
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(detail)
 | 
			
		||||
 | 
			
		||||
constexpr const char *internals_function_record_capsule_name = "pybind11_function_record_capsule";
 | 
			
		||||
 | 
			
		||||
// Forward declarations
 | 
			
		||||
inline PyTypeObject *make_static_property_type();
 | 
			
		||||
inline PyTypeObject *make_default_metaclass();
 | 
			
		||||
inline PyObject *make_object_base_type(PyTypeObject *metaclass);
 | 
			
		||||
 | 
			
		||||
// The old Python Thread Local Storage (TLS) API is deprecated in Python 3.7 in favor of the new
 | 
			
		||||
// Thread Specific Storage (TSS) API.
 | 
			
		||||
#if PY_VERSION_HEX >= 0x03070000
 | 
			
		||||
// Avoid unnecessary allocation of `Py_tss_t`, since we cannot use
 | 
			
		||||
// `Py_LIMITED_API` anyway.
 | 
			
		||||
#    if PYBIND11_INTERNALS_VERSION > 4
 | 
			
		||||
#        define PYBIND11_TLS_KEY_REF Py_tss_t &
 | 
			
		||||
#        if defined(__GNUC__) && !defined(__INTEL_COMPILER)
 | 
			
		||||
// Clang on macOS warns due to `Py_tss_NEEDS_INIT` not specifying an initializer
 | 
			
		||||
// for every field.
 | 
			
		||||
#            define PYBIND11_TLS_KEY_INIT(var)                                                    \
 | 
			
		||||
                _Pragma("GCC diagnostic push")                                         /**/       \
 | 
			
		||||
                    _Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"") /**/       \
 | 
			
		||||
                    Py_tss_t var                                                                  \
 | 
			
		||||
                    = Py_tss_NEEDS_INIT;                                                          \
 | 
			
		||||
                _Pragma("GCC diagnostic pop")
 | 
			
		||||
#        else
 | 
			
		||||
#            define PYBIND11_TLS_KEY_INIT(var) Py_tss_t var = Py_tss_NEEDS_INIT;
 | 
			
		||||
#        endif
 | 
			
		||||
#        define PYBIND11_TLS_KEY_CREATE(var) (PyThread_tss_create(&(var)) == 0)
 | 
			
		||||
#        define PYBIND11_TLS_GET_VALUE(key) PyThread_tss_get(&(key))
 | 
			
		||||
#        define PYBIND11_TLS_REPLACE_VALUE(key, value) PyThread_tss_set(&(key), (value))
 | 
			
		||||
#        define PYBIND11_TLS_DELETE_VALUE(key) PyThread_tss_set(&(key), nullptr)
 | 
			
		||||
#        define PYBIND11_TLS_FREE(key) PyThread_tss_delete(&(key))
 | 
			
		||||
#    else
 | 
			
		||||
#        define PYBIND11_TLS_KEY_REF Py_tss_t *
 | 
			
		||||
#        define PYBIND11_TLS_KEY_INIT(var) Py_tss_t *var = nullptr;
 | 
			
		||||
#        define PYBIND11_TLS_KEY_CREATE(var)                                                      \
 | 
			
		||||
            (((var) = PyThread_tss_alloc()) != nullptr && (PyThread_tss_create((var)) == 0))
 | 
			
		||||
#        define PYBIND11_TLS_GET_VALUE(key) PyThread_tss_get((key))
 | 
			
		||||
#        define PYBIND11_TLS_REPLACE_VALUE(key, value) PyThread_tss_set((key), (value))
 | 
			
		||||
#        define PYBIND11_TLS_DELETE_VALUE(key) PyThread_tss_set((key), nullptr)
 | 
			
		||||
#        define PYBIND11_TLS_FREE(key) PyThread_tss_free(key)
 | 
			
		||||
#    endif
 | 
			
		||||
#else
 | 
			
		||||
// Usually an int but a long on Cygwin64 with Python 3.x
 | 
			
		||||
#    define PYBIND11_TLS_KEY_REF decltype(PyThread_create_key())
 | 
			
		||||
#    define PYBIND11_TLS_KEY_INIT(var) PYBIND11_TLS_KEY_REF var = 0;
 | 
			
		||||
#    define PYBIND11_TLS_KEY_CREATE(var) (((var) = PyThread_create_key()) != -1)
 | 
			
		||||
#    define PYBIND11_TLS_GET_VALUE(key) PyThread_get_key_value((key))
 | 
			
		||||
#    if defined(PYPY_VERSION)
 | 
			
		||||
// On CPython < 3.4 and on PyPy, `PyThread_set_key_value` strangely does not set
 | 
			
		||||
// the value if it has already been set.  Instead, it must first be deleted and
 | 
			
		||||
// then set again.
 | 
			
		||||
inline void tls_replace_value(PYBIND11_TLS_KEY_REF key, void *value) {
 | 
			
		||||
    PyThread_delete_key_value(key);
 | 
			
		||||
    PyThread_set_key_value(key, value);
 | 
			
		||||
}
 | 
			
		||||
#        define PYBIND11_TLS_DELETE_VALUE(key) PyThread_delete_key_value(key)
 | 
			
		||||
#        define PYBIND11_TLS_REPLACE_VALUE(key, value)                                            \
 | 
			
		||||
            ::pybind11::detail::tls_replace_value((key), (value))
 | 
			
		||||
#    else
 | 
			
		||||
#        define PYBIND11_TLS_DELETE_VALUE(key) PyThread_set_key_value((key), nullptr)
 | 
			
		||||
#        define PYBIND11_TLS_REPLACE_VALUE(key, value) PyThread_set_key_value((key), (value))
 | 
			
		||||
#    endif
 | 
			
		||||
#    define PYBIND11_TLS_FREE(key) (void) key
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Python loads modules by default with dlopen with the RTLD_LOCAL flag; under libc++ and possibly
 | 
			
		||||
// other STLs, this means `typeid(A)` from one module won't equal `typeid(A)` from another module
 | 
			
		||||
// even when `A` is the same, non-hidden-visibility type (e.g. from a common include).  Under
 | 
			
		||||
// libstdc++, this doesn't happen: equality and the type_index hash are based on the type name,
 | 
			
		||||
// which works.  If not under a known-good stl, provide our own name-based hash and equality
 | 
			
		||||
// functions that use the type name.
 | 
			
		||||
#if (PYBIND11_INTERNALS_VERSION <= 4 && defined(__GLIBCXX__))                                     \
 | 
			
		||||
    || (PYBIND11_INTERNALS_VERSION >= 5 && !defined(_LIBCPP_VERSION))
 | 
			
		||||
inline bool same_type(const std::type_info &lhs, const std::type_info &rhs) { return lhs == rhs; }
 | 
			
		||||
using type_hash = std::hash<std::type_index>;
 | 
			
		||||
using type_equal_to = std::equal_to<std::type_index>;
 | 
			
		||||
#else
 | 
			
		||||
inline bool same_type(const std::type_info &lhs, const std::type_info &rhs) {
 | 
			
		||||
    return lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct type_hash {
 | 
			
		||||
    size_t operator()(const std::type_index &t) const {
 | 
			
		||||
        size_t hash = 5381;
 | 
			
		||||
        const char *ptr = t.name();
 | 
			
		||||
        while (auto c = static_cast<unsigned char>(*ptr++)) {
 | 
			
		||||
            hash = (hash * 33) ^ c;
 | 
			
		||||
        }
 | 
			
		||||
        return hash;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct type_equal_to {
 | 
			
		||||
    bool operator()(const std::type_index &lhs, const std::type_index &rhs) const {
 | 
			
		||||
        return lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
template <typename value_type>
 | 
			
		||||
using type_map = std::unordered_map<std::type_index, value_type, type_hash, type_equal_to>;
 | 
			
		||||
 | 
			
		||||
struct override_hash {
 | 
			
		||||
    inline size_t operator()(const std::pair<const PyObject *, const char *> &v) const {
 | 
			
		||||
        size_t value = std::hash<const void *>()(v.first);
 | 
			
		||||
        value ^= std::hash<const void *>()(v.second) + 0x9e3779b9 + (value << 6) + (value >> 2);
 | 
			
		||||
        return value;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Internal data structure used to track registered instances and types.
 | 
			
		||||
/// Whenever binary incompatible changes are made to this structure,
 | 
			
		||||
/// `PYBIND11_INTERNALS_VERSION` must be incremented.
 | 
			
		||||
struct internals {
 | 
			
		||||
    // std::type_index -> pybind11's type information
 | 
			
		||||
    type_map<type_info *> registered_types_cpp;
 | 
			
		||||
    // PyTypeObject* -> base type_info(s)
 | 
			
		||||
    std::unordered_map<PyTypeObject *, std::vector<type_info *>> registered_types_py;
 | 
			
		||||
    std::unordered_multimap<const void *, instance *> registered_instances; // void * -> instance*
 | 
			
		||||
    std::unordered_set<std::pair<const PyObject *, const char *>, override_hash>
 | 
			
		||||
        inactive_override_cache;
 | 
			
		||||
    type_map<std::vector<bool (*)(PyObject *, void *&)>> direct_conversions;
 | 
			
		||||
    std::unordered_map<const PyObject *, std::vector<PyObject *>> patients;
 | 
			
		||||
    std::forward_list<ExceptionTranslator> registered_exception_translators;
 | 
			
		||||
    std::unordered_map<std::string, void *> shared_data; // Custom data to be shared across
 | 
			
		||||
                                                         // extensions
 | 
			
		||||
#if PYBIND11_INTERNALS_VERSION == 4
 | 
			
		||||
    std::vector<PyObject *> unused_loader_patient_stack_remove_at_v5;
 | 
			
		||||
#endif
 | 
			
		||||
    std::forward_list<std::string> static_strings; // Stores the std::strings backing
 | 
			
		||||
                                                   // detail::c_str()
 | 
			
		||||
    PyTypeObject *static_property_type;
 | 
			
		||||
    PyTypeObject *default_metaclass;
 | 
			
		||||
    PyObject *instance_base;
 | 
			
		||||
#if defined(WITH_THREAD)
 | 
			
		||||
    // Unused if PYBIND11_SIMPLE_GIL_MANAGEMENT is defined:
 | 
			
		||||
    PYBIND11_TLS_KEY_INIT(tstate)
 | 
			
		||||
#    if PYBIND11_INTERNALS_VERSION > 4
 | 
			
		||||
    PYBIND11_TLS_KEY_INIT(loader_life_support_tls_key)
 | 
			
		||||
#    endif // PYBIND11_INTERNALS_VERSION > 4
 | 
			
		||||
    // Unused if PYBIND11_SIMPLE_GIL_MANAGEMENT is defined:
 | 
			
		||||
    PyInterpreterState *istate = nullptr;
 | 
			
		||||
 | 
			
		||||
#    if PYBIND11_INTERNALS_VERSION > 4
 | 
			
		||||
    // Note that we have to use a std::string to allocate memory to ensure a unique address
 | 
			
		||||
    // We want unique addresses since we use pointer equality to compare function records
 | 
			
		||||
    std::string function_record_capsule_name = internals_function_record_capsule_name;
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
    internals() = default;
 | 
			
		||||
    internals(const internals &other) = delete;
 | 
			
		||||
    internals &operator=(const internals &other) = delete;
 | 
			
		||||
    ~internals() {
 | 
			
		||||
#    if PYBIND11_INTERNALS_VERSION > 4
 | 
			
		||||
        PYBIND11_TLS_FREE(loader_life_support_tls_key);
 | 
			
		||||
#    endif // PYBIND11_INTERNALS_VERSION > 4
 | 
			
		||||
 | 
			
		||||
        // This destructor is called *after* Py_Finalize() in finalize_interpreter().
 | 
			
		||||
        // That *SHOULD BE* fine. The following details what happens when PyThread_tss_free is
 | 
			
		||||
        // called. PYBIND11_TLS_FREE is PyThread_tss_free on python 3.7+. On older python, it does
 | 
			
		||||
        // nothing. PyThread_tss_free calls PyThread_tss_delete and PyMem_RawFree.
 | 
			
		||||
        // PyThread_tss_delete just calls TlsFree (on Windows) or pthread_key_delete (on *NIX).
 | 
			
		||||
        // Neither of those have anything to do with CPython internals. PyMem_RawFree *requires*
 | 
			
		||||
        // that the `tstate` be allocated with the CPython allocator.
 | 
			
		||||
        PYBIND11_TLS_FREE(tstate);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Additional type information which does not fit into the PyTypeObject.
 | 
			
		||||
/// Changes to this struct also require bumping `PYBIND11_INTERNALS_VERSION`.
 | 
			
		||||
struct type_info {
 | 
			
		||||
    PyTypeObject *type;
 | 
			
		||||
    const std::type_info *cpptype;
 | 
			
		||||
    size_t type_size, type_align, holder_size_in_ptrs;
 | 
			
		||||
    void *(*operator_new)(size_t);
 | 
			
		||||
    void (*init_instance)(instance *, const void *);
 | 
			
		||||
    void (*dealloc)(value_and_holder &v_h);
 | 
			
		||||
    std::vector<PyObject *(*) (PyObject *, PyTypeObject *)> implicit_conversions;
 | 
			
		||||
    std::vector<std::pair<const std::type_info *, void *(*) (void *)>> implicit_casts;
 | 
			
		||||
    std::vector<bool (*)(PyObject *, void *&)> *direct_conversions;
 | 
			
		||||
    buffer_info *(*get_buffer)(PyObject *, void *) = nullptr;
 | 
			
		||||
    void *get_buffer_data = nullptr;
 | 
			
		||||
    void *(*module_local_load)(PyObject *, const type_info *) = nullptr;
 | 
			
		||||
    /* A simple type never occurs as a (direct or indirect) parent
 | 
			
		||||
     * of a class that makes use of multiple inheritance.
 | 
			
		||||
     * A type can be simple even if it has non-simple ancestors as long as it has no descendants.
 | 
			
		||||
     */
 | 
			
		||||
    bool simple_type : 1;
 | 
			
		||||
    /* True if there is no multiple inheritance in this type's inheritance tree */
 | 
			
		||||
    bool simple_ancestors : 1;
 | 
			
		||||
    /* for base vs derived holder_type checks */
 | 
			
		||||
    bool default_holder : 1;
 | 
			
		||||
    /* true if this is a type registered with py::module_local */
 | 
			
		||||
    bool module_local : 1;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// On MSVC, debug and release builds are not ABI-compatible!
 | 
			
		||||
#if defined(_MSC_VER) && defined(_DEBUG)
 | 
			
		||||
#    define PYBIND11_BUILD_TYPE "_debug"
 | 
			
		||||
#else
 | 
			
		||||
#    define PYBIND11_BUILD_TYPE ""
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/// Let's assume that different compilers are ABI-incompatible.
 | 
			
		||||
/// A user can manually set this string if they know their
 | 
			
		||||
/// compiler is compatible.
 | 
			
		||||
#ifndef PYBIND11_COMPILER_TYPE
 | 
			
		||||
#    if defined(_MSC_VER)
 | 
			
		||||
#        define PYBIND11_COMPILER_TYPE "_msvc"
 | 
			
		||||
#    elif defined(__INTEL_COMPILER)
 | 
			
		||||
#        define PYBIND11_COMPILER_TYPE "_icc"
 | 
			
		||||
#    elif defined(__clang__)
 | 
			
		||||
#        define PYBIND11_COMPILER_TYPE "_clang"
 | 
			
		||||
#    elif defined(__PGI)
 | 
			
		||||
#        define PYBIND11_COMPILER_TYPE "_pgi"
 | 
			
		||||
#    elif defined(__MINGW32__)
 | 
			
		||||
#        define PYBIND11_COMPILER_TYPE "_mingw"
 | 
			
		||||
#    elif defined(__CYGWIN__)
 | 
			
		||||
#        define PYBIND11_COMPILER_TYPE "_gcc_cygwin"
 | 
			
		||||
#    elif defined(__GNUC__)
 | 
			
		||||
#        define PYBIND11_COMPILER_TYPE "_gcc"
 | 
			
		||||
#    else
 | 
			
		||||
#        define PYBIND11_COMPILER_TYPE "_unknown"
 | 
			
		||||
#    endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/// Also standard libs
 | 
			
		||||
#ifndef PYBIND11_STDLIB
 | 
			
		||||
#    if defined(_LIBCPP_VERSION)
 | 
			
		||||
#        define PYBIND11_STDLIB "_libcpp"
 | 
			
		||||
#    elif defined(__GLIBCXX__) || defined(__GLIBCPP__)
 | 
			
		||||
#        define PYBIND11_STDLIB "_libstdcpp"
 | 
			
		||||
#    else
 | 
			
		||||
#        define PYBIND11_STDLIB ""
 | 
			
		||||
#    endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/// On Linux/OSX, changes in __GXX_ABI_VERSION__ indicate ABI incompatibility.
 | 
			
		||||
#ifndef PYBIND11_BUILD_ABI
 | 
			
		||||
#    if defined(__GXX_ABI_VERSION)
 | 
			
		||||
#        define PYBIND11_BUILD_ABI "_cxxabi" PYBIND11_TOSTRING(__GXX_ABI_VERSION)
 | 
			
		||||
#    else
 | 
			
		||||
#        define PYBIND11_BUILD_ABI ""
 | 
			
		||||
#    endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef PYBIND11_INTERNALS_KIND
 | 
			
		||||
#    if defined(WITH_THREAD)
 | 
			
		||||
#        define PYBIND11_INTERNALS_KIND ""
 | 
			
		||||
#    else
 | 
			
		||||
#        define PYBIND11_INTERNALS_KIND "_without_thread"
 | 
			
		||||
#    endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define PYBIND11_INTERNALS_ID                                                                     \
 | 
			
		||||
    "__pybind11_internals_v" PYBIND11_TOSTRING(PYBIND11_INTERNALS_VERSION)                        \
 | 
			
		||||
        PYBIND11_INTERNALS_KIND PYBIND11_COMPILER_TYPE PYBIND11_STDLIB PYBIND11_BUILD_ABI         \
 | 
			
		||||
            PYBIND11_BUILD_TYPE "__"
 | 
			
		||||
 | 
			
		||||
#define PYBIND11_MODULE_LOCAL_ID                                                                  \
 | 
			
		||||
    "__pybind11_module_local_v" PYBIND11_TOSTRING(PYBIND11_INTERNALS_VERSION)                     \
 | 
			
		||||
        PYBIND11_INTERNALS_KIND PYBIND11_COMPILER_TYPE PYBIND11_STDLIB PYBIND11_BUILD_ABI         \
 | 
			
		||||
            PYBIND11_BUILD_TYPE "__"
 | 
			
		||||
 | 
			
		||||
/// Each module locally stores a pointer to the `internals` data. The data
 | 
			
		||||
/// itself is shared among modules with the same `PYBIND11_INTERNALS_ID`.
 | 
			
		||||
inline internals **&get_internals_pp() {
 | 
			
		||||
    static internals **internals_pp = nullptr;
 | 
			
		||||
    return internals_pp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// forward decl
 | 
			
		||||
inline void translate_exception(std::exception_ptr);
 | 
			
		||||
 | 
			
		||||
template <class T,
 | 
			
		||||
          enable_if_t<std::is_same<std::nested_exception, remove_cvref_t<T>>::value, int> = 0>
 | 
			
		||||
bool handle_nested_exception(const T &exc, const std::exception_ptr &p) {
 | 
			
		||||
    std::exception_ptr nested = exc.nested_ptr();
 | 
			
		||||
    if (nested != nullptr && nested != p) {
 | 
			
		||||
        translate_exception(nested);
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class T,
 | 
			
		||||
          enable_if_t<!std::is_same<std::nested_exception, remove_cvref_t<T>>::value, int> = 0>
 | 
			
		||||
bool handle_nested_exception(const T &exc, const std::exception_ptr &p) {
 | 
			
		||||
    if (const auto *nep = dynamic_cast<const std::nested_exception *>(std::addressof(exc))) {
 | 
			
		||||
        return handle_nested_exception(*nep, p);
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool raise_err(PyObject *exc_type, const char *msg) {
 | 
			
		||||
    if (PyErr_Occurred()) {
 | 
			
		||||
        raise_from(exc_type, msg);
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    PyErr_SetString(exc_type, msg);
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void translate_exception(std::exception_ptr p) {
 | 
			
		||||
    if (!p) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    try {
 | 
			
		||||
        std::rethrow_exception(p);
 | 
			
		||||
    } catch (error_already_set &e) {
 | 
			
		||||
        handle_nested_exception(e, p);
 | 
			
		||||
        e.restore();
 | 
			
		||||
        return;
 | 
			
		||||
    } catch (const builtin_exception &e) {
 | 
			
		||||
        // Could not use template since it's an abstract class.
 | 
			
		||||
        if (const auto *nep = dynamic_cast<const std::nested_exception *>(std::addressof(e))) {
 | 
			
		||||
            handle_nested_exception(*nep, p);
 | 
			
		||||
        }
 | 
			
		||||
        e.set_error();
 | 
			
		||||
        return;
 | 
			
		||||
    } catch (const std::bad_alloc &e) {
 | 
			
		||||
        handle_nested_exception(e, p);
 | 
			
		||||
        raise_err(PyExc_MemoryError, e.what());
 | 
			
		||||
        return;
 | 
			
		||||
    } catch (const std::domain_error &e) {
 | 
			
		||||
        handle_nested_exception(e, p);
 | 
			
		||||
        raise_err(PyExc_ValueError, e.what());
 | 
			
		||||
        return;
 | 
			
		||||
    } catch (const std::invalid_argument &e) {
 | 
			
		||||
        handle_nested_exception(e, p);
 | 
			
		||||
        raise_err(PyExc_ValueError, e.what());
 | 
			
		||||
        return;
 | 
			
		||||
    } catch (const std::length_error &e) {
 | 
			
		||||
        handle_nested_exception(e, p);
 | 
			
		||||
        raise_err(PyExc_ValueError, e.what());
 | 
			
		||||
        return;
 | 
			
		||||
    } catch (const std::out_of_range &e) {
 | 
			
		||||
        handle_nested_exception(e, p);
 | 
			
		||||
        raise_err(PyExc_IndexError, e.what());
 | 
			
		||||
        return;
 | 
			
		||||
    } catch (const std::range_error &e) {
 | 
			
		||||
        handle_nested_exception(e, p);
 | 
			
		||||
        raise_err(PyExc_ValueError, e.what());
 | 
			
		||||
        return;
 | 
			
		||||
    } catch (const std::overflow_error &e) {
 | 
			
		||||
        handle_nested_exception(e, p);
 | 
			
		||||
        raise_err(PyExc_OverflowError, e.what());
 | 
			
		||||
        return;
 | 
			
		||||
    } catch (const std::exception &e) {
 | 
			
		||||
        handle_nested_exception(e, p);
 | 
			
		||||
        raise_err(PyExc_RuntimeError, e.what());
 | 
			
		||||
        return;
 | 
			
		||||
    } catch (const std::nested_exception &e) {
 | 
			
		||||
        handle_nested_exception(e, p);
 | 
			
		||||
        raise_err(PyExc_RuntimeError, "Caught an unknown nested exception!");
 | 
			
		||||
        return;
 | 
			
		||||
    } catch (...) {
 | 
			
		||||
        raise_err(PyExc_RuntimeError, "Caught an unknown exception!");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if !defined(__GLIBCXX__)
 | 
			
		||||
inline void translate_local_exception(std::exception_ptr p) {
 | 
			
		||||
    try {
 | 
			
		||||
        if (p) {
 | 
			
		||||
            std::rethrow_exception(p);
 | 
			
		||||
        }
 | 
			
		||||
    } catch (error_already_set &e) {
 | 
			
		||||
        e.restore();
 | 
			
		||||
        return;
 | 
			
		||||
    } catch (const builtin_exception &e) {
 | 
			
		||||
        e.set_error();
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
inline object get_python_state_dict() {
 | 
			
		||||
    object state_dict;
 | 
			
		||||
#if PYBIND11_INTERNALS_VERSION <= 4 || PY_VERSION_HEX < 0x03080000 || defined(PYPY_VERSION)
 | 
			
		||||
    state_dict = reinterpret_borrow<object>(PyEval_GetBuiltins());
 | 
			
		||||
#else
 | 
			
		||||
#    if PY_VERSION_HEX < 0x03090000
 | 
			
		||||
    PyInterpreterState *istate = _PyInterpreterState_Get();
 | 
			
		||||
#    else
 | 
			
		||||
    PyInterpreterState *istate = PyInterpreterState_Get();
 | 
			
		||||
#    endif
 | 
			
		||||
    if (istate) {
 | 
			
		||||
        state_dict = reinterpret_borrow<object>(PyInterpreterState_GetDict(istate));
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    if (!state_dict) {
 | 
			
		||||
        raise_from(PyExc_SystemError, "pybind11::detail::get_python_state_dict() FAILED");
 | 
			
		||||
    }
 | 
			
		||||
    return state_dict;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline object get_internals_obj_from_state_dict(handle state_dict) {
 | 
			
		||||
    return reinterpret_borrow<object>(dict_getitemstring(state_dict.ptr(), PYBIND11_INTERNALS_ID));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline internals **get_internals_pp_from_capsule(handle obj) {
 | 
			
		||||
    void *raw_ptr = PyCapsule_GetPointer(obj.ptr(), /*name=*/nullptr);
 | 
			
		||||
    if (raw_ptr == nullptr) {
 | 
			
		||||
        raise_from(PyExc_SystemError, "pybind11::detail::get_internals_pp_from_capsule() FAILED");
 | 
			
		||||
    }
 | 
			
		||||
    return static_cast<internals **>(raw_ptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Return a reference to the current `internals` data
 | 
			
		||||
PYBIND11_NOINLINE internals &get_internals() {
 | 
			
		||||
    auto **&internals_pp = get_internals_pp();
 | 
			
		||||
    if (internals_pp && *internals_pp) {
 | 
			
		||||
        return **internals_pp;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if defined(WITH_THREAD)
 | 
			
		||||
#    if defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)
 | 
			
		||||
    gil_scoped_acquire gil;
 | 
			
		||||
#    else
 | 
			
		||||
    // Ensure that the GIL is held since we will need to make Python calls.
 | 
			
		||||
    // Cannot use py::gil_scoped_acquire here since that constructor calls get_internals.
 | 
			
		||||
    struct gil_scoped_acquire_local {
 | 
			
		||||
        gil_scoped_acquire_local() : state(PyGILState_Ensure()) {}
 | 
			
		||||
        gil_scoped_acquire_local(const gil_scoped_acquire_local &) = delete;
 | 
			
		||||
        gil_scoped_acquire_local &operator=(const gil_scoped_acquire_local &) = delete;
 | 
			
		||||
        ~gil_scoped_acquire_local() { PyGILState_Release(state); }
 | 
			
		||||
        const PyGILState_STATE state;
 | 
			
		||||
    } gil;
 | 
			
		||||
#    endif
 | 
			
		||||
#endif
 | 
			
		||||
    error_scope err_scope;
 | 
			
		||||
 | 
			
		||||
    dict state_dict = get_python_state_dict();
 | 
			
		||||
    if (object internals_obj = get_internals_obj_from_state_dict(state_dict)) {
 | 
			
		||||
        internals_pp = get_internals_pp_from_capsule(internals_obj);
 | 
			
		||||
    }
 | 
			
		||||
    if (internals_pp && *internals_pp) {
 | 
			
		||||
        // We loaded the internals through `state_dict`, which means that our `error_already_set`
 | 
			
		||||
        // and `builtin_exception` may be different local classes than the ones set up in the
 | 
			
		||||
        // initial exception translator, below, so add another for our local exception classes.
 | 
			
		||||
        //
 | 
			
		||||
        // libstdc++ doesn't require this (types there are identified only by name)
 | 
			
		||||
        // libc++ with CPython doesn't require this (types are explicitly exported)
 | 
			
		||||
        // libc++ with PyPy still need it, awaiting further investigation
 | 
			
		||||
#if !defined(__GLIBCXX__)
 | 
			
		||||
        (*internals_pp)->registered_exception_translators.push_front(&translate_local_exception);
 | 
			
		||||
#endif
 | 
			
		||||
    } else {
 | 
			
		||||
        if (!internals_pp) {
 | 
			
		||||
            internals_pp = new internals *();
 | 
			
		||||
        }
 | 
			
		||||
        auto *&internals_ptr = *internals_pp;
 | 
			
		||||
        internals_ptr = new internals();
 | 
			
		||||
#if defined(WITH_THREAD)
 | 
			
		||||
 | 
			
		||||
        PyThreadState *tstate = PyThreadState_Get();
 | 
			
		||||
        // NOLINTNEXTLINE(bugprone-assignment-in-if-condition)
 | 
			
		||||
        if (!PYBIND11_TLS_KEY_CREATE(internals_ptr->tstate)) {
 | 
			
		||||
            pybind11_fail("get_internals: could not successfully initialize the tstate TSS key!");
 | 
			
		||||
        }
 | 
			
		||||
        PYBIND11_TLS_REPLACE_VALUE(internals_ptr->tstate, tstate);
 | 
			
		||||
 | 
			
		||||
#    if PYBIND11_INTERNALS_VERSION > 4
 | 
			
		||||
        // NOLINTNEXTLINE(bugprone-assignment-in-if-condition)
 | 
			
		||||
        if (!PYBIND11_TLS_KEY_CREATE(internals_ptr->loader_life_support_tls_key)) {
 | 
			
		||||
            pybind11_fail("get_internals: could not successfully initialize the "
 | 
			
		||||
                          "loader_life_support TSS key!");
 | 
			
		||||
        }
 | 
			
		||||
#    endif
 | 
			
		||||
        internals_ptr->istate = tstate->interp;
 | 
			
		||||
#endif
 | 
			
		||||
        state_dict[PYBIND11_INTERNALS_ID] = capsule(internals_pp);
 | 
			
		||||
        internals_ptr->registered_exception_translators.push_front(&translate_exception);
 | 
			
		||||
        internals_ptr->static_property_type = make_static_property_type();
 | 
			
		||||
        internals_ptr->default_metaclass = make_default_metaclass();
 | 
			
		||||
        internals_ptr->instance_base = make_object_base_type(internals_ptr->default_metaclass);
 | 
			
		||||
    }
 | 
			
		||||
    return **internals_pp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// the internals struct (above) is shared between all the modules. local_internals are only
 | 
			
		||||
// for a single module. Any changes made to internals may require an update to
 | 
			
		||||
// PYBIND11_INTERNALS_VERSION, breaking backwards compatibility. local_internals is, by design,
 | 
			
		||||
// restricted to a single module. Whether a module has local internals or not should not
 | 
			
		||||
// impact any other modules, because the only things accessing the local internals is the
 | 
			
		||||
// module that contains them.
 | 
			
		||||
struct local_internals {
 | 
			
		||||
    type_map<type_info *> registered_types_cpp;
 | 
			
		||||
    std::forward_list<ExceptionTranslator> registered_exception_translators;
 | 
			
		||||
#if defined(WITH_THREAD) && PYBIND11_INTERNALS_VERSION == 4
 | 
			
		||||
 | 
			
		||||
    // For ABI compatibility, we can't store the loader_life_support TLS key in
 | 
			
		||||
    // the `internals` struct directly.  Instead, we store it in `shared_data` and
 | 
			
		||||
    // cache a copy in `local_internals`.  If we allocated a separate TLS key for
 | 
			
		||||
    // each instance of `local_internals`, we could end up allocating hundreds of
 | 
			
		||||
    // TLS keys if hundreds of different pybind11 modules are loaded (which is a
 | 
			
		||||
    // plausible number).
 | 
			
		||||
    PYBIND11_TLS_KEY_INIT(loader_life_support_tls_key)
 | 
			
		||||
 | 
			
		||||
    // Holds the shared TLS key for the loader_life_support stack.
 | 
			
		||||
    struct shared_loader_life_support_data {
 | 
			
		||||
        PYBIND11_TLS_KEY_INIT(loader_life_support_tls_key)
 | 
			
		||||
        shared_loader_life_support_data() {
 | 
			
		||||
            // NOLINTNEXTLINE(bugprone-assignment-in-if-condition)
 | 
			
		||||
            if (!PYBIND11_TLS_KEY_CREATE(loader_life_support_tls_key)) {
 | 
			
		||||
                pybind11_fail("local_internals: could not successfully initialize the "
 | 
			
		||||
                              "loader_life_support TLS key!");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        // We can't help but leak the TLS key, because Python never unloads extension modules.
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    local_internals() {
 | 
			
		||||
        auto &internals = get_internals();
 | 
			
		||||
        // Get or create the `loader_life_support_stack_key`.
 | 
			
		||||
        auto &ptr = internals.shared_data["_life_support"];
 | 
			
		||||
        if (!ptr) {
 | 
			
		||||
            ptr = new shared_loader_life_support_data;
 | 
			
		||||
        }
 | 
			
		||||
        loader_life_support_tls_key
 | 
			
		||||
            = static_cast<shared_loader_life_support_data *>(ptr)->loader_life_support_tls_key;
 | 
			
		||||
    }
 | 
			
		||||
#endif //  defined(WITH_THREAD) && PYBIND11_INTERNALS_VERSION == 4
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Works like `get_internals`, but for things which are locally registered.
 | 
			
		||||
inline local_internals &get_local_internals() {
 | 
			
		||||
    // Current static can be created in the interpreter finalization routine. If the later will be
 | 
			
		||||
    // destroyed in another static variable destructor, creation of this static there will cause
 | 
			
		||||
    // static deinitialization fiasco. In order to avoid it we avoid destruction of the
 | 
			
		||||
    // local_internals static. One can read more about the problem and current solution here:
 | 
			
		||||
    // https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables
 | 
			
		||||
    static auto *locals = new local_internals();
 | 
			
		||||
    return *locals;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Constructs a std::string with the given arguments, stores it in `internals`, and returns its
 | 
			
		||||
/// `c_str()`.  Such strings objects have a long storage duration -- the internal strings are only
 | 
			
		||||
/// cleared when the program exits or after interpreter shutdown (when embedding), and so are
 | 
			
		||||
/// suitable for c-style strings needed by Python internals (such as PyTypeObject's tp_name).
 | 
			
		||||
template <typename... Args>
 | 
			
		||||
const char *c_str(Args &&...args) {
 | 
			
		||||
    auto &strings = get_internals().static_strings;
 | 
			
		||||
    strings.emplace_front(std::forward<Args>(args)...);
 | 
			
		||||
    return strings.front().c_str();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline const char *get_function_record_capsule_name() {
 | 
			
		||||
#if PYBIND11_INTERNALS_VERSION > 4
 | 
			
		||||
    return get_internals().function_record_capsule_name.c_str();
 | 
			
		||||
#else
 | 
			
		||||
    return nullptr;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Determine whether or not the following capsule contains a pybind11 function record.
 | 
			
		||||
// Note that we use `internals` to make sure that only ABI compatible records are touched.
 | 
			
		||||
//
 | 
			
		||||
// This check is currently used in two places:
 | 
			
		||||
// - An important optimization in functional.h to avoid overhead in C++ -> Python -> C++
 | 
			
		||||
// - The sibling feature of cpp_function to allow overloads
 | 
			
		||||
inline bool is_function_record_capsule(const capsule &cap) {
 | 
			
		||||
    // Pointer equality as we rely on internals() to ensure unique pointers
 | 
			
		||||
    return cap.name() == get_function_record_capsule_name();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_END(detail)
 | 
			
		||||
 | 
			
		||||
/// Returns a named pointer that is shared among all extension modules (using the same
 | 
			
		||||
/// pybind11 version) running in the current interpreter. Names starting with underscores
 | 
			
		||||
/// are reserved for internal usage. Returns `nullptr` if no matching entry was found.
 | 
			
		||||
PYBIND11_NOINLINE void *get_shared_data(const std::string &name) {
 | 
			
		||||
    auto &internals = detail::get_internals();
 | 
			
		||||
    auto it = internals.shared_data.find(name);
 | 
			
		||||
    return it != internals.shared_data.end() ? it->second : nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Set the shared data that can be later recovered by `get_shared_data()`.
 | 
			
		||||
PYBIND11_NOINLINE void *set_shared_data(const std::string &name, void *data) {
 | 
			
		||||
    detail::get_internals().shared_data[name] = data;
 | 
			
		||||
    return data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Returns a typed reference to a shared data entry (by using `get_shared_data()`) if
 | 
			
		||||
/// such entry exists. Otherwise, a new object of default-constructible type `T` is
 | 
			
		||||
/// added to the shared data under the given name and a reference to it is returned.
 | 
			
		||||
template <typename T>
 | 
			
		||||
T &get_or_create_shared_data(const std::string &name) {
 | 
			
		||||
    auto &internals = detail::get_internals();
 | 
			
		||||
    auto it = internals.shared_data.find(name);
 | 
			
		||||
    T *ptr = (T *) (it != internals.shared_data.end() ? it->second : nullptr);
 | 
			
		||||
    if (!ptr) {
 | 
			
		||||
        ptr = new T();
 | 
			
		||||
        internals.shared_data[name] = ptr;
 | 
			
		||||
    }
 | 
			
		||||
    return *ptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
 | 
			
		||||
							
								
								
									
										1177
									
								
								3rdparty/pybind11/include/pybind11/detail/type_caster_base.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1177
									
								
								3rdparty/pybind11/include/pybind11/detail/type_caster_base.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										65
									
								
								3rdparty/pybind11/include/pybind11/detail/typeid.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								3rdparty/pybind11/include/pybind11/detail/typeid.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,65 @@
 | 
			
		||||
/*
 | 
			
		||||
    pybind11/detail/typeid.h: Compiler-independent access to type identifiers
 | 
			
		||||
 | 
			
		||||
    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
 | 
			
		||||
 | 
			
		||||
    All rights reserved. Use of this source code is governed by a
 | 
			
		||||
    BSD-style license that can be found in the LICENSE file.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
 | 
			
		||||
#if defined(__GNUG__)
 | 
			
		||||
#    include <cxxabi.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "common.h"
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(detail)
 | 
			
		||||
 | 
			
		||||
/// Erase all occurrences of a substring
 | 
			
		||||
inline void erase_all(std::string &string, const std::string &search) {
 | 
			
		||||
    for (size_t pos = 0;;) {
 | 
			
		||||
        pos = string.find(search, pos);
 | 
			
		||||
        if (pos == std::string::npos) {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        string.erase(pos, search.length());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PYBIND11_NOINLINE void clean_type_id(std::string &name) {
 | 
			
		||||
#if defined(__GNUG__)
 | 
			
		||||
    int status = 0;
 | 
			
		||||
    std::unique_ptr<char, void (*)(void *)> res{
 | 
			
		||||
        abi::__cxa_demangle(name.c_str(), nullptr, nullptr, &status), std::free};
 | 
			
		||||
    if (status == 0) {
 | 
			
		||||
        name = res.get();
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
    detail::erase_all(name, "class ");
 | 
			
		||||
    detail::erase_all(name, "struct ");
 | 
			
		||||
    detail::erase_all(name, "enum ");
 | 
			
		||||
#endif
 | 
			
		||||
    detail::erase_all(name, "pybind11::");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline std::string clean_type_id(const char *typeid_name) {
 | 
			
		||||
    std::string name(typeid_name);
 | 
			
		||||
    detail::clean_type_id(name);
 | 
			
		||||
    return name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_END(detail)
 | 
			
		||||
 | 
			
		||||
/// Return a string representation of a C++ type
 | 
			
		||||
template <typename T>
 | 
			
		||||
static std::string type_id() {
 | 
			
		||||
    return detail::clean_type_id(typeid(T).name());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
 | 
			
		||||
							
								
								
									
										12
									
								
								3rdparty/pybind11/include/pybind11/eigen.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								3rdparty/pybind11/include/pybind11/eigen.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
/*
 | 
			
		||||
    pybind11/eigen.h: Transparent conversion for dense and sparse Eigen matrices
 | 
			
		||||
 | 
			
		||||
    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
 | 
			
		||||
 | 
			
		||||
    All rights reserved. Use of this source code is governed by a
 | 
			
		||||
    BSD-style license that can be found in the LICENSE file.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "eigen/matrix.h"
 | 
			
		||||
							
								
								
									
										9
									
								
								3rdparty/pybind11/include/pybind11/eigen/common.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								3rdparty/pybind11/include/pybind11/eigen/common.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
// Copyright (c) 2023 The pybind Community.
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
// Common message for `static_assert()`s, which are useful to easily
 | 
			
		||||
// preempt much less obvious errors.
 | 
			
		||||
#define PYBIND11_EIGEN_MESSAGE_POINTER_TYPES_ARE_NOT_SUPPORTED                                    \
 | 
			
		||||
    "Pointer types (in particular `PyObject *`) are not supported as scalar types for Eigen "     \
 | 
			
		||||
    "types."
 | 
			
		||||
							
								
								
									
										714
									
								
								3rdparty/pybind11/include/pybind11/eigen/matrix.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										714
									
								
								3rdparty/pybind11/include/pybind11/eigen/matrix.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,714 @@
 | 
			
		||||
/*
 | 
			
		||||
    pybind11/eigen/matrix.h: Transparent conversion for dense and sparse Eigen matrices
 | 
			
		||||
 | 
			
		||||
    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
 | 
			
		||||
 | 
			
		||||
    All rights reserved. Use of this source code is governed by a
 | 
			
		||||
    BSD-style license that can be found in the LICENSE file.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "../numpy.h"
 | 
			
		||||
#include "common.h"
 | 
			
		||||
 | 
			
		||||
/* HINT: To suppress warnings originating from the Eigen headers, use -isystem.
 | 
			
		||||
   See also:
 | 
			
		||||
       https://stackoverflow.com/questions/2579576/i-dir-vs-isystem-dir
 | 
			
		||||
       https://stackoverflow.com/questions/1741816/isystem-for-ms-visual-studio-c-compiler
 | 
			
		||||
*/
 | 
			
		||||
PYBIND11_WARNING_PUSH
 | 
			
		||||
PYBIND11_WARNING_DISABLE_MSVC(5054) // https://github.com/pybind/pybind11/pull/3741
 | 
			
		||||
//       C5054: operator '&': deprecated between enumerations of different types
 | 
			
		||||
#if defined(__MINGW32__)
 | 
			
		||||
PYBIND11_WARNING_DISABLE_GCC("-Wmaybe-uninitialized")
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <Eigen/Core>
 | 
			
		||||
#include <Eigen/SparseCore>
 | 
			
		||||
 | 
			
		||||
PYBIND11_WARNING_POP
 | 
			
		||||
 | 
			
		||||
// Eigen prior to 3.2.7 doesn't have proper move constructors--but worse, some classes get implicit
 | 
			
		||||
// move constructors that break things.  We could detect this an explicitly copy, but an extra copy
 | 
			
		||||
// of matrices seems highly undesirable.
 | 
			
		||||
static_assert(EIGEN_VERSION_AT_LEAST(3, 2, 7),
 | 
			
		||||
              "Eigen matrix support in pybind11 requires Eigen >= 3.2.7");
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
 | 
			
		||||
 | 
			
		||||
PYBIND11_WARNING_DISABLE_MSVC(4127)
 | 
			
		||||
 | 
			
		||||
// Provide a convenience alias for easier pass-by-ref usage with fully dynamic strides:
 | 
			
		||||
using EigenDStride = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
 | 
			
		||||
template <typename MatrixType>
 | 
			
		||||
using EigenDRef = Eigen::Ref<MatrixType, 0, EigenDStride>;
 | 
			
		||||
template <typename MatrixType>
 | 
			
		||||
using EigenDMap = Eigen::Map<MatrixType, 0, EigenDStride>;
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(detail)
 | 
			
		||||
 | 
			
		||||
#if EIGEN_VERSION_AT_LEAST(3, 3, 0)
 | 
			
		||||
using EigenIndex = Eigen::Index;
 | 
			
		||||
template <typename Scalar, int Flags, typename StorageIndex>
 | 
			
		||||
using EigenMapSparseMatrix = Eigen::Map<Eigen::SparseMatrix<Scalar, Flags, StorageIndex>>;
 | 
			
		||||
#else
 | 
			
		||||
using EigenIndex = EIGEN_DEFAULT_DENSE_INDEX_TYPE;
 | 
			
		||||
template <typename Scalar, int Flags, typename StorageIndex>
 | 
			
		||||
using EigenMapSparseMatrix = Eigen::MappedSparseMatrix<Scalar, Flags, StorageIndex>;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Matches Eigen::Map, Eigen::Ref, blocks, etc:
 | 
			
		||||
template <typename T>
 | 
			
		||||
using is_eigen_dense_map = all_of<is_template_base_of<Eigen::DenseBase, T>,
 | 
			
		||||
                                  std::is_base_of<Eigen::MapBase<T, Eigen::ReadOnlyAccessors>, T>>;
 | 
			
		||||
template <typename T>
 | 
			
		||||
using is_eigen_mutable_map = std::is_base_of<Eigen::MapBase<T, Eigen::WriteAccessors>, T>;
 | 
			
		||||
template <typename T>
 | 
			
		||||
using is_eigen_dense_plain
 | 
			
		||||
    = all_of<negation<is_eigen_dense_map<T>>, is_template_base_of<Eigen::PlainObjectBase, T>>;
 | 
			
		||||
template <typename T>
 | 
			
		||||
using is_eigen_sparse = is_template_base_of<Eigen::SparseMatrixBase, T>;
 | 
			
		||||
// Test for objects inheriting from EigenBase<Derived> that aren't captured by the above.  This
 | 
			
		||||
// basically covers anything that can be assigned to a dense matrix but that don't have a typical
 | 
			
		||||
// matrix data layout that can be copied from their .data().  For example, DiagonalMatrix and
 | 
			
		||||
// SelfAdjointView fall into this category.
 | 
			
		||||
template <typename T>
 | 
			
		||||
using is_eigen_other
 | 
			
		||||
    = all_of<is_template_base_of<Eigen::EigenBase, T>,
 | 
			
		||||
             negation<any_of<is_eigen_dense_map<T>, is_eigen_dense_plain<T>, is_eigen_sparse<T>>>>;
 | 
			
		||||
 | 
			
		||||
// Captures numpy/eigen conformability status (returned by EigenProps::conformable()):
 | 
			
		||||
template <bool EigenRowMajor>
 | 
			
		||||
struct EigenConformable {
 | 
			
		||||
    bool conformable = false;
 | 
			
		||||
    EigenIndex rows = 0, cols = 0;
 | 
			
		||||
    EigenDStride stride{0, 0};    // Only valid if negativestrides is false!
 | 
			
		||||
    bool negativestrides = false; // If true, do not use stride!
 | 
			
		||||
 | 
			
		||||
    // NOLINTNEXTLINE(google-explicit-constructor)
 | 
			
		||||
    EigenConformable(bool fits = false) : conformable{fits} {}
 | 
			
		||||
    // Matrix type:
 | 
			
		||||
    EigenConformable(EigenIndex r, EigenIndex c, EigenIndex rstride, EigenIndex cstride)
 | 
			
		||||
        : conformable{true}, rows{r}, cols{c},
 | 
			
		||||
          // TODO: when Eigen bug #747 is fixed, remove the tests for non-negativity.
 | 
			
		||||
          // http://eigen.tuxfamily.org/bz/show_bug.cgi?id=747
 | 
			
		||||
          stride{EigenRowMajor ? (rstride > 0 ? rstride : 0)
 | 
			
		||||
                               : (cstride > 0 ? cstride : 0) /* outer stride */,
 | 
			
		||||
                 EigenRowMajor ? (cstride > 0 ? cstride : 0)
 | 
			
		||||
                               : (rstride > 0 ? rstride : 0) /* inner stride */},
 | 
			
		||||
          negativestrides{rstride < 0 || cstride < 0} {}
 | 
			
		||||
    // Vector type:
 | 
			
		||||
    EigenConformable(EigenIndex r, EigenIndex c, EigenIndex stride)
 | 
			
		||||
        : EigenConformable(r, c, r == 1 ? c * stride : stride, c == 1 ? r : r * stride) {}
 | 
			
		||||
 | 
			
		||||
    template <typename props>
 | 
			
		||||
    bool stride_compatible() const {
 | 
			
		||||
        // To have compatible strides, we need (on both dimensions) one of fully dynamic strides,
 | 
			
		||||
        // matching strides, or a dimension size of 1 (in which case the stride value is
 | 
			
		||||
        // irrelevant). Alternatively, if any dimension size is 0, the strides are not relevant
 | 
			
		||||
        // (and numpy ≥ 1.23 sets the strides to 0 in that case, so we need to check explicitly).
 | 
			
		||||
        if (negativestrides) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (rows == 0 || cols == 0) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        return (props::inner_stride == Eigen::Dynamic || props::inner_stride == stride.inner()
 | 
			
		||||
                || (EigenRowMajor ? cols : rows) == 1)
 | 
			
		||||
               && (props::outer_stride == Eigen::Dynamic || props::outer_stride == stride.outer()
 | 
			
		||||
                   || (EigenRowMajor ? rows : cols) == 1);
 | 
			
		||||
    }
 | 
			
		||||
    // NOLINTNEXTLINE(google-explicit-constructor)
 | 
			
		||||
    operator bool() const { return conformable; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename Type>
 | 
			
		||||
struct eigen_extract_stride {
 | 
			
		||||
    using type = Type;
 | 
			
		||||
};
 | 
			
		||||
template <typename PlainObjectType, int MapOptions, typename StrideType>
 | 
			
		||||
struct eigen_extract_stride<Eigen::Map<PlainObjectType, MapOptions, StrideType>> {
 | 
			
		||||
    using type = StrideType;
 | 
			
		||||
};
 | 
			
		||||
template <typename PlainObjectType, int Options, typename StrideType>
 | 
			
		||||
struct eigen_extract_stride<Eigen::Ref<PlainObjectType, Options, StrideType>> {
 | 
			
		||||
    using type = StrideType;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Helper struct for extracting information from an Eigen type
 | 
			
		||||
template <typename Type_>
 | 
			
		||||
struct EigenProps {
 | 
			
		||||
    using Type = Type_;
 | 
			
		||||
    using Scalar = typename Type::Scalar;
 | 
			
		||||
    using StrideType = typename eigen_extract_stride<Type>::type;
 | 
			
		||||
    static constexpr EigenIndex rows = Type::RowsAtCompileTime, cols = Type::ColsAtCompileTime,
 | 
			
		||||
                                size = Type::SizeAtCompileTime;
 | 
			
		||||
    static constexpr bool row_major = Type::IsRowMajor,
 | 
			
		||||
                          vector
 | 
			
		||||
                          = Type::IsVectorAtCompileTime, // At least one dimension has fixed size 1
 | 
			
		||||
        fixed_rows = rows != Eigen::Dynamic, fixed_cols = cols != Eigen::Dynamic,
 | 
			
		||||
                          fixed = size != Eigen::Dynamic, // Fully-fixed size
 | 
			
		||||
        dynamic = !fixed_rows && !fixed_cols;             // Fully-dynamic size
 | 
			
		||||
 | 
			
		||||
    template <EigenIndex i, EigenIndex ifzero>
 | 
			
		||||
    using if_zero = std::integral_constant<EigenIndex, i == 0 ? ifzero : i>;
 | 
			
		||||
    static constexpr EigenIndex inner_stride
 | 
			
		||||
        = if_zero<StrideType::InnerStrideAtCompileTime, 1>::value,
 | 
			
		||||
        outer_stride = if_zero < StrideType::OuterStrideAtCompileTime,
 | 
			
		||||
        vector      ? size
 | 
			
		||||
        : row_major ? cols
 | 
			
		||||
                    : rows > ::value;
 | 
			
		||||
    static constexpr bool dynamic_stride
 | 
			
		||||
        = inner_stride == Eigen::Dynamic && outer_stride == Eigen::Dynamic;
 | 
			
		||||
    static constexpr bool requires_row_major
 | 
			
		||||
        = !dynamic_stride && !vector && (row_major ? inner_stride : outer_stride) == 1;
 | 
			
		||||
    static constexpr bool requires_col_major
 | 
			
		||||
        = !dynamic_stride && !vector && (row_major ? outer_stride : inner_stride) == 1;
 | 
			
		||||
 | 
			
		||||
    // Takes an input array and determines whether we can make it fit into the Eigen type.  If
 | 
			
		||||
    // the array is a vector, we attempt to fit it into either an Eigen 1xN or Nx1 vector
 | 
			
		||||
    // (preferring the latter if it will fit in either, i.e. for a fully dynamic matrix type).
 | 
			
		||||
    static EigenConformable<row_major> conformable(const array &a) {
 | 
			
		||||
        const auto dims = a.ndim();
 | 
			
		||||
        if (dims < 1 || dims > 2) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (dims == 2) { // Matrix type: require exact match (or dynamic)
 | 
			
		||||
 | 
			
		||||
            EigenIndex np_rows = a.shape(0), np_cols = a.shape(1),
 | 
			
		||||
                       np_rstride = a.strides(0) / static_cast<ssize_t>(sizeof(Scalar)),
 | 
			
		||||
                       np_cstride = a.strides(1) / static_cast<ssize_t>(sizeof(Scalar));
 | 
			
		||||
            if ((fixed_rows && np_rows != rows) || (fixed_cols && np_cols != cols)) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return {np_rows, np_cols, np_rstride, np_cstride};
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Otherwise we're storing an n-vector.  Only one of the strides will be used, but
 | 
			
		||||
        // whichever is used, we want the (single) numpy stride value.
 | 
			
		||||
        const EigenIndex n = a.shape(0),
 | 
			
		||||
                         stride = a.strides(0) / static_cast<ssize_t>(sizeof(Scalar));
 | 
			
		||||
 | 
			
		||||
        if (vector) { // Eigen type is a compile-time vector
 | 
			
		||||
            if (fixed && size != n) {
 | 
			
		||||
                return false; // Vector size mismatch
 | 
			
		||||
            }
 | 
			
		||||
            return {rows == 1 ? 1 : n, cols == 1 ? 1 : n, stride};
 | 
			
		||||
        }
 | 
			
		||||
        if (fixed) {
 | 
			
		||||
            // The type has a fixed size, but is not a vector: abort
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (fixed_cols) {
 | 
			
		||||
            // Since this isn't a vector, cols must be != 1.  We allow this only if it exactly
 | 
			
		||||
            // equals the number of elements (rows is Dynamic, and so 1 row is allowed).
 | 
			
		||||
            if (cols != n) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            return {1, n, stride};
 | 
			
		||||
        } // Otherwise it's either fully dynamic, or column dynamic; both become a column vector
 | 
			
		||||
        if (fixed_rows && rows != n) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        return {n, 1, stride};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static constexpr bool show_writeable
 | 
			
		||||
        = is_eigen_dense_map<Type>::value && is_eigen_mutable_map<Type>::value;
 | 
			
		||||
    static constexpr bool show_order = is_eigen_dense_map<Type>::value;
 | 
			
		||||
    static constexpr bool show_c_contiguous = show_order && requires_row_major;
 | 
			
		||||
    static constexpr bool show_f_contiguous
 | 
			
		||||
        = !show_c_contiguous && show_order && requires_col_major;
 | 
			
		||||
 | 
			
		||||
    static constexpr auto descriptor
 | 
			
		||||
        = const_name("numpy.ndarray[") + npy_format_descriptor<Scalar>::name + const_name("[")
 | 
			
		||||
          + const_name<fixed_rows>(const_name<(size_t) rows>(), const_name("m")) + const_name(", ")
 | 
			
		||||
          + const_name<fixed_cols>(const_name<(size_t) cols>(), const_name("n")) + const_name("]")
 | 
			
		||||
          +
 | 
			
		||||
          // For a reference type (e.g. Ref<MatrixXd>) we have other constraints that might need to
 | 
			
		||||
          // be satisfied: writeable=True (for a mutable reference), and, depending on the map's
 | 
			
		||||
          // stride options, possibly f_contiguous or c_contiguous.  We include them in the
 | 
			
		||||
          // descriptor output to provide some hint as to why a TypeError is occurring (otherwise
 | 
			
		||||
          // it can be confusing to see that a function accepts a 'numpy.ndarray[float64[3,2]]' and
 | 
			
		||||
          // an error message that you *gave* a numpy.ndarray of the right type and dimensions.
 | 
			
		||||
          const_name<show_writeable>(", flags.writeable", "")
 | 
			
		||||
          + const_name<show_c_contiguous>(", flags.c_contiguous", "")
 | 
			
		||||
          + const_name<show_f_contiguous>(", flags.f_contiguous", "") + const_name("]");
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Casts an Eigen type to numpy array.  If given a base, the numpy array references the src data,
 | 
			
		||||
// otherwise it'll make a copy.  writeable lets you turn off the writeable flag for the array.
 | 
			
		||||
template <typename props>
 | 
			
		||||
handle
 | 
			
		||||
eigen_array_cast(typename props::Type const &src, handle base = handle(), bool writeable = true) {
 | 
			
		||||
    constexpr ssize_t elem_size = sizeof(typename props::Scalar);
 | 
			
		||||
    array a;
 | 
			
		||||
    if (props::vector) {
 | 
			
		||||
        a = array({src.size()}, {elem_size * src.innerStride()}, src.data(), base);
 | 
			
		||||
    } else {
 | 
			
		||||
        a = array({src.rows(), src.cols()},
 | 
			
		||||
                  {elem_size * src.rowStride(), elem_size * src.colStride()},
 | 
			
		||||
                  src.data(),
 | 
			
		||||
                  base);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!writeable) {
 | 
			
		||||
        array_proxy(a.ptr())->flags &= ~detail::npy_api::NPY_ARRAY_WRITEABLE_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return a.release();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Takes an lvalue ref to some Eigen type and a (python) base object, creating a numpy array that
 | 
			
		||||
// reference the Eigen object's data with `base` as the python-registered base class (if omitted,
 | 
			
		||||
// the base will be set to None, and lifetime management is up to the caller).  The numpy array is
 | 
			
		||||
// non-writeable if the given type is const.
 | 
			
		||||
template <typename props, typename Type>
 | 
			
		||||
handle eigen_ref_array(Type &src, handle parent = none()) {
 | 
			
		||||
    // none here is to get past array's should-we-copy detection, which currently always
 | 
			
		||||
    // copies when there is no base.  Setting the base to None should be harmless.
 | 
			
		||||
    return eigen_array_cast<props>(src, parent, !std::is_const<Type>::value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Takes a pointer to some dense, plain Eigen type, builds a capsule around it, then returns a
 | 
			
		||||
// numpy array that references the encapsulated data with a python-side reference to the capsule to
 | 
			
		||||
// tie its destruction to that of any dependent python objects.  Const-ness is determined by
 | 
			
		||||
// whether or not the Type of the pointer given is const.
 | 
			
		||||
template <typename props, typename Type, typename = enable_if_t<is_eigen_dense_plain<Type>::value>>
 | 
			
		||||
handle eigen_encapsulate(Type *src) {
 | 
			
		||||
    capsule base(src, [](void *o) { delete static_cast<Type *>(o); });
 | 
			
		||||
    return eigen_ref_array<props>(*src, base);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Type caster for regular, dense matrix types (e.g. MatrixXd), but not maps/refs/etc. of dense
 | 
			
		||||
// types.
 | 
			
		||||
template <typename Type>
 | 
			
		||||
struct type_caster<Type, enable_if_t<is_eigen_dense_plain<Type>::value>> {
 | 
			
		||||
    using Scalar = typename Type::Scalar;
 | 
			
		||||
    static_assert(!std::is_pointer<Scalar>::value,
 | 
			
		||||
                  PYBIND11_EIGEN_MESSAGE_POINTER_TYPES_ARE_NOT_SUPPORTED);
 | 
			
		||||
    using props = EigenProps<Type>;
 | 
			
		||||
 | 
			
		||||
    bool load(handle src, bool convert) {
 | 
			
		||||
        // If we're in no-convert mode, only load if given an array of the correct type
 | 
			
		||||
        if (!convert && !isinstance<array_t<Scalar>>(src)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Coerce into an array, but don't do type conversion yet; the copy below handles it.
 | 
			
		||||
        auto buf = array::ensure(src);
 | 
			
		||||
 | 
			
		||||
        if (!buf) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        auto dims = buf.ndim();
 | 
			
		||||
        if (dims < 1 || dims > 2) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        auto fits = props::conformable(buf);
 | 
			
		||||
        if (!fits) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Allocate the new type, then build a numpy reference into it
 | 
			
		||||
        value = Type(fits.rows, fits.cols);
 | 
			
		||||
        auto ref = reinterpret_steal<array>(eigen_ref_array<props>(value));
 | 
			
		||||
        if (dims == 1) {
 | 
			
		||||
            ref = ref.squeeze();
 | 
			
		||||
        } else if (ref.ndim() == 1) {
 | 
			
		||||
            buf = buf.squeeze();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        int result = detail::npy_api::get().PyArray_CopyInto_(ref.ptr(), buf.ptr());
 | 
			
		||||
 | 
			
		||||
        if (result < 0) { // Copy failed!
 | 
			
		||||
            PyErr_Clear();
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    // Cast implementation
 | 
			
		||||
    template <typename CType>
 | 
			
		||||
    static handle cast_impl(CType *src, return_value_policy policy, handle parent) {
 | 
			
		||||
        switch (policy) {
 | 
			
		||||
            case return_value_policy::take_ownership:
 | 
			
		||||
            case return_value_policy::automatic:
 | 
			
		||||
                return eigen_encapsulate<props>(src);
 | 
			
		||||
            case return_value_policy::move:
 | 
			
		||||
                return eigen_encapsulate<props>(new CType(std::move(*src)));
 | 
			
		||||
            case return_value_policy::copy:
 | 
			
		||||
                return eigen_array_cast<props>(*src);
 | 
			
		||||
            case return_value_policy::reference:
 | 
			
		||||
            case return_value_policy::automatic_reference:
 | 
			
		||||
                return eigen_ref_array<props>(*src);
 | 
			
		||||
            case return_value_policy::reference_internal:
 | 
			
		||||
                return eigen_ref_array<props>(*src, parent);
 | 
			
		||||
            default:
 | 
			
		||||
                throw cast_error("unhandled return_value_policy: should not happen!");
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    // Normal returned non-reference, non-const value:
 | 
			
		||||
    static handle cast(Type &&src, return_value_policy /* policy */, handle parent) {
 | 
			
		||||
        return cast_impl(&src, return_value_policy::move, parent);
 | 
			
		||||
    }
 | 
			
		||||
    // If you return a non-reference const, we mark the numpy array readonly:
 | 
			
		||||
    static handle cast(const Type &&src, return_value_policy /* policy */, handle parent) {
 | 
			
		||||
        return cast_impl(&src, return_value_policy::move, parent);
 | 
			
		||||
    }
 | 
			
		||||
    // lvalue reference return; default (automatic) becomes copy
 | 
			
		||||
    static handle cast(Type &src, return_value_policy policy, handle parent) {
 | 
			
		||||
        if (policy == return_value_policy::automatic
 | 
			
		||||
            || policy == return_value_policy::automatic_reference) {
 | 
			
		||||
            policy = return_value_policy::copy;
 | 
			
		||||
        }
 | 
			
		||||
        return cast_impl(&src, policy, parent);
 | 
			
		||||
    }
 | 
			
		||||
    // const lvalue reference return; default (automatic) becomes copy
 | 
			
		||||
    static handle cast(const Type &src, return_value_policy policy, handle parent) {
 | 
			
		||||
        if (policy == return_value_policy::automatic
 | 
			
		||||
            || policy == return_value_policy::automatic_reference) {
 | 
			
		||||
            policy = return_value_policy::copy;
 | 
			
		||||
        }
 | 
			
		||||
        return cast(&src, policy, parent);
 | 
			
		||||
    }
 | 
			
		||||
    // non-const pointer return
 | 
			
		||||
    static handle cast(Type *src, return_value_policy policy, handle parent) {
 | 
			
		||||
        return cast_impl(src, policy, parent);
 | 
			
		||||
    }
 | 
			
		||||
    // const pointer return
 | 
			
		||||
    static handle cast(const Type *src, return_value_policy policy, handle parent) {
 | 
			
		||||
        return cast_impl(src, policy, parent);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static constexpr auto name = props::descriptor;
 | 
			
		||||
 | 
			
		||||
    // NOLINTNEXTLINE(google-explicit-constructor)
 | 
			
		||||
    operator Type *() { return &value; }
 | 
			
		||||
    // NOLINTNEXTLINE(google-explicit-constructor)
 | 
			
		||||
    operator Type &() { return value; }
 | 
			
		||||
    // NOLINTNEXTLINE(google-explicit-constructor)
 | 
			
		||||
    operator Type &&() && { return std::move(value); }
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    using cast_op_type = movable_cast_op_type<T>;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    Type value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Base class for casting reference/map/block/etc. objects back to python.
 | 
			
		||||
template <typename MapType>
 | 
			
		||||
struct eigen_map_caster {
 | 
			
		||||
    static_assert(!std::is_pointer<typename MapType::Scalar>::value,
 | 
			
		||||
                  PYBIND11_EIGEN_MESSAGE_POINTER_TYPES_ARE_NOT_SUPPORTED);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    using props = EigenProps<MapType>;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    // Directly referencing a ref/map's data is a bit dangerous (whatever the map/ref points to has
 | 
			
		||||
    // to stay around), but we'll allow it under the assumption that you know what you're doing
 | 
			
		||||
    // (and have an appropriate keep_alive in place).  We return a numpy array pointing directly at
 | 
			
		||||
    // the ref's data (The numpy array ends up read-only if the ref was to a const matrix type.)
 | 
			
		||||
    // Note that this means you need to ensure you don't destroy the object in some other way (e.g.
 | 
			
		||||
    // with an appropriate keep_alive, or with a reference to a statically allocated matrix).
 | 
			
		||||
    static handle cast(const MapType &src, return_value_policy policy, handle parent) {
 | 
			
		||||
        switch (policy) {
 | 
			
		||||
            case return_value_policy::copy:
 | 
			
		||||
                return eigen_array_cast<props>(src);
 | 
			
		||||
            case return_value_policy::reference_internal:
 | 
			
		||||
                return eigen_array_cast<props>(src, parent, is_eigen_mutable_map<MapType>::value);
 | 
			
		||||
            case return_value_policy::reference:
 | 
			
		||||
            case return_value_policy::automatic:
 | 
			
		||||
            case return_value_policy::automatic_reference:
 | 
			
		||||
                return eigen_array_cast<props>(src, none(), is_eigen_mutable_map<MapType>::value);
 | 
			
		||||
            default:
 | 
			
		||||
                // move, take_ownership don't make any sense for a ref/map:
 | 
			
		||||
                pybind11_fail("Invalid return_value_policy for Eigen Map/Ref/Block type");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static constexpr auto name = props::descriptor;
 | 
			
		||||
 | 
			
		||||
    // Explicitly delete these: support python -> C++ conversion on these (i.e. these can be return
 | 
			
		||||
    // types but not bound arguments).  We still provide them (with an explicitly delete) so that
 | 
			
		||||
    // you end up here if you try anyway.
 | 
			
		||||
    bool load(handle, bool) = delete;
 | 
			
		||||
    operator MapType() = delete;
 | 
			
		||||
    template <typename>
 | 
			
		||||
    using cast_op_type = MapType;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// We can return any map-like object (but can only load Refs, specialized next):
 | 
			
		||||
template <typename Type>
 | 
			
		||||
struct type_caster<Type, enable_if_t<is_eigen_dense_map<Type>::value>> : eigen_map_caster<Type> {};
 | 
			
		||||
 | 
			
		||||
// Loader for Ref<...> arguments.  See the documentation for info on how to make this work without
 | 
			
		||||
// copying (it requires some extra effort in many cases).
 | 
			
		||||
template <typename PlainObjectType, typename StrideType>
 | 
			
		||||
struct type_caster<
 | 
			
		||||
    Eigen::Ref<PlainObjectType, 0, StrideType>,
 | 
			
		||||
    enable_if_t<is_eigen_dense_map<Eigen::Ref<PlainObjectType, 0, StrideType>>::value>>
 | 
			
		||||
    : public eigen_map_caster<Eigen::Ref<PlainObjectType, 0, StrideType>> {
 | 
			
		||||
private:
 | 
			
		||||
    using Type = Eigen::Ref<PlainObjectType, 0, StrideType>;
 | 
			
		||||
    using props = EigenProps<Type>;
 | 
			
		||||
    using Scalar = typename props::Scalar;
 | 
			
		||||
    static_assert(!std::is_pointer<Scalar>::value,
 | 
			
		||||
                  PYBIND11_EIGEN_MESSAGE_POINTER_TYPES_ARE_NOT_SUPPORTED);
 | 
			
		||||
    using MapType = Eigen::Map<PlainObjectType, 0, StrideType>;
 | 
			
		||||
    using Array
 | 
			
		||||
        = array_t<Scalar,
 | 
			
		||||
                  array::forcecast
 | 
			
		||||
                      | ((props::row_major ? props::inner_stride : props::outer_stride) == 1
 | 
			
		||||
                             ? array::c_style
 | 
			
		||||
                         : (props::row_major ? props::outer_stride : props::inner_stride) == 1
 | 
			
		||||
                             ? array::f_style
 | 
			
		||||
                             : 0)>;
 | 
			
		||||
    static constexpr bool need_writeable = is_eigen_mutable_map<Type>::value;
 | 
			
		||||
    // Delay construction (these have no default constructor)
 | 
			
		||||
    std::unique_ptr<MapType> map;
 | 
			
		||||
    std::unique_ptr<Type> ref;
 | 
			
		||||
    // Our array.  When possible, this is just a numpy array pointing to the source data, but
 | 
			
		||||
    // sometimes we can't avoid copying (e.g. input is not a numpy array at all, has an
 | 
			
		||||
    // incompatible layout, or is an array of a type that needs to be converted).  Using a numpy
 | 
			
		||||
    // temporary (rather than an Eigen temporary) saves an extra copy when we need both type
 | 
			
		||||
    // conversion and storage order conversion.  (Note that we refuse to use this temporary copy
 | 
			
		||||
    // when loading an argument for a Ref<M> with M non-const, i.e. a read-write reference).
 | 
			
		||||
    Array copy_or_ref;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    bool load(handle src, bool convert) {
 | 
			
		||||
        // First check whether what we have is already an array of the right type.  If not, we
 | 
			
		||||
        // can't avoid a copy (because the copy is also going to do type conversion).
 | 
			
		||||
        bool need_copy = !isinstance<Array>(src);
 | 
			
		||||
 | 
			
		||||
        EigenConformable<props::row_major> fits;
 | 
			
		||||
        if (!need_copy) {
 | 
			
		||||
            // We don't need a converting copy, but we also need to check whether the strides are
 | 
			
		||||
            // compatible with the Ref's stride requirements
 | 
			
		||||
            auto aref = reinterpret_borrow<Array>(src);
 | 
			
		||||
 | 
			
		||||
            if (aref && (!need_writeable || aref.writeable())) {
 | 
			
		||||
                fits = props::conformable(aref);
 | 
			
		||||
                if (!fits) {
 | 
			
		||||
                    return false; // Incompatible dimensions
 | 
			
		||||
                }
 | 
			
		||||
                if (!fits.template stride_compatible<props>()) {
 | 
			
		||||
                    need_copy = true;
 | 
			
		||||
                } else {
 | 
			
		||||
                    copy_or_ref = std::move(aref);
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                need_copy = true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (need_copy) {
 | 
			
		||||
            // We need to copy: If we need a mutable reference, or we're not supposed to convert
 | 
			
		||||
            // (either because we're in the no-convert overload pass, or because we're explicitly
 | 
			
		||||
            // instructed not to copy (via `py::arg().noconvert()`) we have to fail loading.
 | 
			
		||||
            if (!convert || need_writeable) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Array copy = Array::ensure(src);
 | 
			
		||||
            if (!copy) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            fits = props::conformable(copy);
 | 
			
		||||
            if (!fits || !fits.template stride_compatible<props>()) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            copy_or_ref = std::move(copy);
 | 
			
		||||
            loader_life_support::add_patient(copy_or_ref);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ref.reset();
 | 
			
		||||
        map.reset(new MapType(data(copy_or_ref),
 | 
			
		||||
                              fits.rows,
 | 
			
		||||
                              fits.cols,
 | 
			
		||||
                              make_stride(fits.stride.outer(), fits.stride.inner())));
 | 
			
		||||
        ref.reset(new Type(*map));
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // NOLINTNEXTLINE(google-explicit-constructor)
 | 
			
		||||
    operator Type *() { return ref.get(); }
 | 
			
		||||
    // NOLINTNEXTLINE(google-explicit-constructor)
 | 
			
		||||
    operator Type &() { return *ref; }
 | 
			
		||||
    template <typename _T>
 | 
			
		||||
    using cast_op_type = pybind11::detail::cast_op_type<_T>;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    template <typename T = Type, enable_if_t<is_eigen_mutable_map<T>::value, int> = 0>
 | 
			
		||||
    Scalar *data(Array &a) {
 | 
			
		||||
        return a.mutable_data();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <typename T = Type, enable_if_t<!is_eigen_mutable_map<T>::value, int> = 0>
 | 
			
		||||
    const Scalar *data(Array &a) {
 | 
			
		||||
        return a.data();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Attempt to figure out a constructor of `Stride` that will work.
 | 
			
		||||
    // If both strides are fixed, use a default constructor:
 | 
			
		||||
    template <typename S>
 | 
			
		||||
    using stride_ctor_default = bool_constant<S::InnerStrideAtCompileTime != Eigen::Dynamic
 | 
			
		||||
                                              && S::OuterStrideAtCompileTime != Eigen::Dynamic
 | 
			
		||||
                                              && std::is_default_constructible<S>::value>;
 | 
			
		||||
    // Otherwise, if there is a two-index constructor, assume it is (outer,inner) like
 | 
			
		||||
    // Eigen::Stride, and use it:
 | 
			
		||||
    template <typename S>
 | 
			
		||||
    using stride_ctor_dual
 | 
			
		||||
        = bool_constant<!stride_ctor_default<S>::value
 | 
			
		||||
                        && std::is_constructible<S, EigenIndex, EigenIndex>::value>;
 | 
			
		||||
    // Otherwise, if there is a one-index constructor, and just one of the strides is dynamic, use
 | 
			
		||||
    // it (passing whichever stride is dynamic).
 | 
			
		||||
    template <typename S>
 | 
			
		||||
    using stride_ctor_outer
 | 
			
		||||
        = bool_constant<!any_of<stride_ctor_default<S>, stride_ctor_dual<S>>::value
 | 
			
		||||
                        && S::OuterStrideAtCompileTime == Eigen::Dynamic
 | 
			
		||||
                        && S::InnerStrideAtCompileTime != Eigen::Dynamic
 | 
			
		||||
                        && std::is_constructible<S, EigenIndex>::value>;
 | 
			
		||||
    template <typename S>
 | 
			
		||||
    using stride_ctor_inner
 | 
			
		||||
        = bool_constant<!any_of<stride_ctor_default<S>, stride_ctor_dual<S>>::value
 | 
			
		||||
                        && S::InnerStrideAtCompileTime == Eigen::Dynamic
 | 
			
		||||
                        && S::OuterStrideAtCompileTime != Eigen::Dynamic
 | 
			
		||||
                        && std::is_constructible<S, EigenIndex>::value>;
 | 
			
		||||
 | 
			
		||||
    template <typename S = StrideType, enable_if_t<stride_ctor_default<S>::value, int> = 0>
 | 
			
		||||
    static S make_stride(EigenIndex, EigenIndex) {
 | 
			
		||||
        return S();
 | 
			
		||||
    }
 | 
			
		||||
    template <typename S = StrideType, enable_if_t<stride_ctor_dual<S>::value, int> = 0>
 | 
			
		||||
    static S make_stride(EigenIndex outer, EigenIndex inner) {
 | 
			
		||||
        return S(outer, inner);
 | 
			
		||||
    }
 | 
			
		||||
    template <typename S = StrideType, enable_if_t<stride_ctor_outer<S>::value, int> = 0>
 | 
			
		||||
    static S make_stride(EigenIndex outer, EigenIndex) {
 | 
			
		||||
        return S(outer);
 | 
			
		||||
    }
 | 
			
		||||
    template <typename S = StrideType, enable_if_t<stride_ctor_inner<S>::value, int> = 0>
 | 
			
		||||
    static S make_stride(EigenIndex, EigenIndex inner) {
 | 
			
		||||
        return S(inner);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// type_caster for special matrix types (e.g. DiagonalMatrix), which are EigenBase, but not
 | 
			
		||||
// EigenDense (i.e. they don't have a data(), at least not with the usual matrix layout).
 | 
			
		||||
// load() is not supported, but we can cast them into the python domain by first copying to a
 | 
			
		||||
// regular Eigen::Matrix, then casting that.
 | 
			
		||||
template <typename Type>
 | 
			
		||||
struct type_caster<Type, enable_if_t<is_eigen_other<Type>::value>> {
 | 
			
		||||
    static_assert(!std::is_pointer<typename Type::Scalar>::value,
 | 
			
		||||
                  PYBIND11_EIGEN_MESSAGE_POINTER_TYPES_ARE_NOT_SUPPORTED);
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    using Matrix
 | 
			
		||||
        = Eigen::Matrix<typename Type::Scalar, Type::RowsAtCompileTime, Type::ColsAtCompileTime>;
 | 
			
		||||
    using props = EigenProps<Matrix>;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    static handle cast(const Type &src, return_value_policy /* policy */, handle /* parent */) {
 | 
			
		||||
        handle h = eigen_encapsulate<props>(new Matrix(src));
 | 
			
		||||
        return h;
 | 
			
		||||
    }
 | 
			
		||||
    static handle cast(const Type *src, return_value_policy policy, handle parent) {
 | 
			
		||||
        return cast(*src, policy, parent);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static constexpr auto name = props::descriptor;
 | 
			
		||||
 | 
			
		||||
    // Explicitly delete these: support python -> C++ conversion on these (i.e. these can be return
 | 
			
		||||
    // types but not bound arguments).  We still provide them (with an explicitly delete) so that
 | 
			
		||||
    // you end up here if you try anyway.
 | 
			
		||||
    bool load(handle, bool) = delete;
 | 
			
		||||
    operator Type() = delete;
 | 
			
		||||
    template <typename>
 | 
			
		||||
    using cast_op_type = Type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename Type>
 | 
			
		||||
struct type_caster<Type, enable_if_t<is_eigen_sparse<Type>::value>> {
 | 
			
		||||
    using Scalar = typename Type::Scalar;
 | 
			
		||||
    static_assert(!std::is_pointer<Scalar>::value,
 | 
			
		||||
                  PYBIND11_EIGEN_MESSAGE_POINTER_TYPES_ARE_NOT_SUPPORTED);
 | 
			
		||||
    using StorageIndex = remove_reference_t<decltype(*std::declval<Type>().outerIndexPtr())>;
 | 
			
		||||
    using Index = typename Type::Index;
 | 
			
		||||
    static constexpr bool rowMajor = Type::IsRowMajor;
 | 
			
		||||
 | 
			
		||||
    bool load(handle src, bool) {
 | 
			
		||||
        if (!src) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        auto obj = reinterpret_borrow<object>(src);
 | 
			
		||||
        object sparse_module = module_::import("scipy.sparse");
 | 
			
		||||
        object matrix_type = sparse_module.attr(rowMajor ? "csr_matrix" : "csc_matrix");
 | 
			
		||||
 | 
			
		||||
        if (!type::handle_of(obj).is(matrix_type)) {
 | 
			
		||||
            try {
 | 
			
		||||
                obj = matrix_type(obj);
 | 
			
		||||
            } catch (const error_already_set &) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        auto values = array_t<Scalar>((object) obj.attr("data"));
 | 
			
		||||
        auto innerIndices = array_t<StorageIndex>((object) obj.attr("indices"));
 | 
			
		||||
        auto outerIndices = array_t<StorageIndex>((object) obj.attr("indptr"));
 | 
			
		||||
        auto shape = pybind11::tuple((pybind11::object) obj.attr("shape"));
 | 
			
		||||
        auto nnz = obj.attr("nnz").cast<Index>();
 | 
			
		||||
 | 
			
		||||
        if (!values || !innerIndices || !outerIndices) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        value = EigenMapSparseMatrix<Scalar,
 | 
			
		||||
                                     Type::Flags &(Eigen::RowMajor | Eigen::ColMajor),
 | 
			
		||||
                                     StorageIndex>(shape[0].cast<Index>(),
 | 
			
		||||
                                                   shape[1].cast<Index>(),
 | 
			
		||||
                                                   std::move(nnz),
 | 
			
		||||
                                                   outerIndices.mutable_data(),
 | 
			
		||||
                                                   innerIndices.mutable_data(),
 | 
			
		||||
                                                   values.mutable_data());
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static handle cast(const Type &src, return_value_policy /* policy */, handle /* parent */) {
 | 
			
		||||
        const_cast<Type &>(src).makeCompressed();
 | 
			
		||||
 | 
			
		||||
        object matrix_type
 | 
			
		||||
            = module_::import("scipy.sparse").attr(rowMajor ? "csr_matrix" : "csc_matrix");
 | 
			
		||||
 | 
			
		||||
        array data(src.nonZeros(), src.valuePtr());
 | 
			
		||||
        array outerIndices((rowMajor ? src.rows() : src.cols()) + 1, src.outerIndexPtr());
 | 
			
		||||
        array innerIndices(src.nonZeros(), src.innerIndexPtr());
 | 
			
		||||
 | 
			
		||||
        return matrix_type(pybind11::make_tuple(
 | 
			
		||||
                               std::move(data), std::move(innerIndices), std::move(outerIndices)),
 | 
			
		||||
                           pybind11::make_tuple(src.rows(), src.cols()))
 | 
			
		||||
            .release();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    PYBIND11_TYPE_CASTER(Type,
 | 
			
		||||
                         const_name<(Type::IsRowMajor) != 0>("scipy.sparse.csr_matrix[",
 | 
			
		||||
                                                             "scipy.sparse.csc_matrix[")
 | 
			
		||||
                             + npy_format_descriptor<Scalar>::name + const_name("]"));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_END(detail)
 | 
			
		||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
 | 
			
		||||
							
								
								
									
										516
									
								
								3rdparty/pybind11/include/pybind11/eigen/tensor.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										516
									
								
								3rdparty/pybind11/include/pybind11/eigen/tensor.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,516 @@
 | 
			
		||||
/*
 | 
			
		||||
    pybind11/eigen/tensor.h: Transparent conversion for Eigen tensors
 | 
			
		||||
 | 
			
		||||
    All rights reserved. Use of this source code is governed by a
 | 
			
		||||
    BSD-style license that can be found in the LICENSE file.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "../numpy.h"
 | 
			
		||||
#include "common.h"
 | 
			
		||||
 | 
			
		||||
#if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER)
 | 
			
		||||
static_assert(__GNUC__ > 5, "Eigen Tensor support in pybind11 requires GCC > 5.0");
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Disable warnings for Eigen
 | 
			
		||||
PYBIND11_WARNING_PUSH
 | 
			
		||||
PYBIND11_WARNING_DISABLE_MSVC(4554)
 | 
			
		||||
PYBIND11_WARNING_DISABLE_MSVC(4127)
 | 
			
		||||
#if defined(__MINGW32__)
 | 
			
		||||
PYBIND11_WARNING_DISABLE_GCC("-Wmaybe-uninitialized")
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <unsupported/Eigen/CXX11/Tensor>
 | 
			
		||||
 | 
			
		||||
PYBIND11_WARNING_POP
 | 
			
		||||
 | 
			
		||||
static_assert(EIGEN_VERSION_AT_LEAST(3, 3, 0),
 | 
			
		||||
              "Eigen Tensor support in pybind11 requires Eigen >= 3.3.0");
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
 | 
			
		||||
 | 
			
		||||
PYBIND11_WARNING_DISABLE_MSVC(4127)
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(detail)
 | 
			
		||||
 | 
			
		||||
inline bool is_tensor_aligned(const void *data) {
 | 
			
		||||
    return (reinterpret_cast<std::size_t>(data) % EIGEN_DEFAULT_ALIGN_BYTES) == 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
constexpr int compute_array_flag_from_tensor() {
 | 
			
		||||
    static_assert((static_cast<int>(T::Layout) == static_cast<int>(Eigen::RowMajor))
 | 
			
		||||
                      || (static_cast<int>(T::Layout) == static_cast<int>(Eigen::ColMajor)),
 | 
			
		||||
                  "Layout must be row or column major");
 | 
			
		||||
    return (static_cast<int>(T::Layout) == static_cast<int>(Eigen::RowMajor)) ? array::c_style
 | 
			
		||||
                                                                              : array::f_style;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct eigen_tensor_helper {};
 | 
			
		||||
 | 
			
		||||
template <typename Scalar_, int NumIndices_, int Options_, typename IndexType>
 | 
			
		||||
struct eigen_tensor_helper<Eigen::Tensor<Scalar_, NumIndices_, Options_, IndexType>> {
 | 
			
		||||
    using Type = Eigen::Tensor<Scalar_, NumIndices_, Options_, IndexType>;
 | 
			
		||||
    using ValidType = void;
 | 
			
		||||
 | 
			
		||||
    static Eigen::DSizes<typename Type::Index, Type::NumIndices> get_shape(const Type &f) {
 | 
			
		||||
        return f.dimensions();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static constexpr bool
 | 
			
		||||
    is_correct_shape(const Eigen::DSizes<typename Type::Index, Type::NumIndices> & /*shape*/) {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    struct helper {};
 | 
			
		||||
 | 
			
		||||
    template <size_t... Is>
 | 
			
		||||
    struct helper<index_sequence<Is...>> {
 | 
			
		||||
        static constexpr auto value = concat(const_name(((void) Is, "?"))...);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    static constexpr auto dimensions_descriptor
 | 
			
		||||
        = helper<decltype(make_index_sequence<Type::NumIndices>())>::value;
 | 
			
		||||
 | 
			
		||||
    template <typename... Args>
 | 
			
		||||
    static Type *alloc(Args &&...args) {
 | 
			
		||||
        return new Type(std::forward<Args>(args)...);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static void free(Type *tensor) { delete tensor; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename Scalar_, typename std::ptrdiff_t... Indices, int Options_, typename IndexType>
 | 
			
		||||
struct eigen_tensor_helper<
 | 
			
		||||
    Eigen::TensorFixedSize<Scalar_, Eigen::Sizes<Indices...>, Options_, IndexType>> {
 | 
			
		||||
    using Type = Eigen::TensorFixedSize<Scalar_, Eigen::Sizes<Indices...>, Options_, IndexType>;
 | 
			
		||||
    using ValidType = void;
 | 
			
		||||
 | 
			
		||||
    static constexpr Eigen::DSizes<typename Type::Index, Type::NumIndices>
 | 
			
		||||
    get_shape(const Type & /*f*/) {
 | 
			
		||||
        return get_shape();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static constexpr Eigen::DSizes<typename Type::Index, Type::NumIndices> get_shape() {
 | 
			
		||||
        return Eigen::DSizes<typename Type::Index, Type::NumIndices>(Indices...);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static bool
 | 
			
		||||
    is_correct_shape(const Eigen::DSizes<typename Type::Index, Type::NumIndices> &shape) {
 | 
			
		||||
        return get_shape() == shape;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static constexpr auto dimensions_descriptor = concat(const_name<Indices>()...);
 | 
			
		||||
 | 
			
		||||
    template <typename... Args>
 | 
			
		||||
    static Type *alloc(Args &&...args) {
 | 
			
		||||
        Eigen::aligned_allocator<Type> allocator;
 | 
			
		||||
        return ::new (allocator.allocate(1)) Type(std::forward<Args>(args)...);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static void free(Type *tensor) {
 | 
			
		||||
        Eigen::aligned_allocator<Type> allocator;
 | 
			
		||||
        tensor->~Type();
 | 
			
		||||
        allocator.deallocate(tensor, 1);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename Type, bool ShowDetails, bool NeedsWriteable = false>
 | 
			
		||||
struct get_tensor_descriptor {
 | 
			
		||||
    static constexpr auto details
 | 
			
		||||
        = const_name<NeedsWriteable>(", flags.writeable", "")
 | 
			
		||||
          + const_name<static_cast<int>(Type::Layout) == static_cast<int>(Eigen::RowMajor)>(
 | 
			
		||||
              ", flags.c_contiguous", ", flags.f_contiguous");
 | 
			
		||||
    static constexpr auto value
 | 
			
		||||
        = const_name("numpy.ndarray[") + npy_format_descriptor<typename Type::Scalar>::name
 | 
			
		||||
          + const_name("[") + eigen_tensor_helper<remove_cv_t<Type>>::dimensions_descriptor
 | 
			
		||||
          + const_name("]") + const_name<ShowDetails>(details, const_name("")) + const_name("]");
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// When EIGEN_AVOID_STL_ARRAY is defined, Eigen::DSizes<T, 0> does not have the begin() member
 | 
			
		||||
// function. Falling back to a simple loop works around this issue.
 | 
			
		||||
//
 | 
			
		||||
// We need to disable the type-limits warning for the inner loop when size = 0.
 | 
			
		||||
 | 
			
		||||
PYBIND11_WARNING_PUSH
 | 
			
		||||
PYBIND11_WARNING_DISABLE_GCC("-Wtype-limits")
 | 
			
		||||
 | 
			
		||||
template <typename T, int size>
 | 
			
		||||
std::vector<T> convert_dsizes_to_vector(const Eigen::DSizes<T, size> &arr) {
 | 
			
		||||
    std::vector<T> result(size);
 | 
			
		||||
 | 
			
		||||
    for (size_t i = 0; i < size; i++) {
 | 
			
		||||
        result[i] = arr[i];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T, int size>
 | 
			
		||||
Eigen::DSizes<T, size> get_shape_for_array(const array &arr) {
 | 
			
		||||
    Eigen::DSizes<T, size> result;
 | 
			
		||||
    const T *shape = arr.shape();
 | 
			
		||||
    for (size_t i = 0; i < size; i++) {
 | 
			
		||||
        result[i] = shape[i];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PYBIND11_WARNING_POP
 | 
			
		||||
 | 
			
		||||
template <typename Type>
 | 
			
		||||
struct type_caster<Type, typename eigen_tensor_helper<Type>::ValidType> {
 | 
			
		||||
    static_assert(!std::is_pointer<typename Type::Scalar>::value,
 | 
			
		||||
                  PYBIND11_EIGEN_MESSAGE_POINTER_TYPES_ARE_NOT_SUPPORTED);
 | 
			
		||||
    using Helper = eigen_tensor_helper<Type>;
 | 
			
		||||
    static constexpr auto temp_name = get_tensor_descriptor<Type, false>::value;
 | 
			
		||||
    PYBIND11_TYPE_CASTER(Type, temp_name);
 | 
			
		||||
 | 
			
		||||
    bool load(handle src, bool convert) {
 | 
			
		||||
        if (!convert) {
 | 
			
		||||
            if (!isinstance<array>(src)) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            array temp = array::ensure(src);
 | 
			
		||||
            if (!temp) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!temp.dtype().is(dtype::of<typename Type::Scalar>())) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        array_t<typename Type::Scalar, compute_array_flag_from_tensor<Type>()> arr(
 | 
			
		||||
            reinterpret_borrow<object>(src));
 | 
			
		||||
 | 
			
		||||
        if (arr.ndim() != Type::NumIndices) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        auto shape = get_shape_for_array<typename Type::Index, Type::NumIndices>(arr);
 | 
			
		||||
 | 
			
		||||
        if (!Helper::is_correct_shape(shape)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#if EIGEN_VERSION_AT_LEAST(3, 4, 0)
 | 
			
		||||
        auto data_pointer = arr.data();
 | 
			
		||||
#else
 | 
			
		||||
        // Handle Eigen bug
 | 
			
		||||
        auto data_pointer = const_cast<typename Type::Scalar *>(arr.data());
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        if (is_tensor_aligned(arr.data())) {
 | 
			
		||||
            value = Eigen::TensorMap<const Type, Eigen::Aligned>(data_pointer, shape);
 | 
			
		||||
        } else {
 | 
			
		||||
            value = Eigen::TensorMap<const Type>(data_pointer, shape);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static handle cast(Type &&src, return_value_policy policy, handle parent) {
 | 
			
		||||
        if (policy == return_value_policy::reference
 | 
			
		||||
            || policy == return_value_policy::reference_internal) {
 | 
			
		||||
            pybind11_fail("Cannot use a reference return value policy for an rvalue");
 | 
			
		||||
        }
 | 
			
		||||
        return cast_impl(&src, return_value_policy::move, parent);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static handle cast(const Type &&src, return_value_policy policy, handle parent) {
 | 
			
		||||
        if (policy == return_value_policy::reference
 | 
			
		||||
            || policy == return_value_policy::reference_internal) {
 | 
			
		||||
            pybind11_fail("Cannot use a reference return value policy for an rvalue");
 | 
			
		||||
        }
 | 
			
		||||
        return cast_impl(&src, return_value_policy::move, parent);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static handle cast(Type &src, return_value_policy policy, handle parent) {
 | 
			
		||||
        if (policy == return_value_policy::automatic
 | 
			
		||||
            || policy == return_value_policy::automatic_reference) {
 | 
			
		||||
            policy = return_value_policy::copy;
 | 
			
		||||
        }
 | 
			
		||||
        return cast_impl(&src, policy, parent);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static handle cast(const Type &src, return_value_policy policy, handle parent) {
 | 
			
		||||
        if (policy == return_value_policy::automatic
 | 
			
		||||
            || policy == return_value_policy::automatic_reference) {
 | 
			
		||||
            policy = return_value_policy::copy;
 | 
			
		||||
        }
 | 
			
		||||
        return cast(&src, policy, parent);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static handle cast(Type *src, return_value_policy policy, handle parent) {
 | 
			
		||||
        if (policy == return_value_policy::automatic) {
 | 
			
		||||
            policy = return_value_policy::take_ownership;
 | 
			
		||||
        } else if (policy == return_value_policy::automatic_reference) {
 | 
			
		||||
            policy = return_value_policy::reference;
 | 
			
		||||
        }
 | 
			
		||||
        return cast_impl(src, policy, parent);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static handle cast(const Type *src, return_value_policy policy, handle parent) {
 | 
			
		||||
        if (policy == return_value_policy::automatic) {
 | 
			
		||||
            policy = return_value_policy::take_ownership;
 | 
			
		||||
        } else if (policy == return_value_policy::automatic_reference) {
 | 
			
		||||
            policy = return_value_policy::reference;
 | 
			
		||||
        }
 | 
			
		||||
        return cast_impl(src, policy, parent);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <typename C>
 | 
			
		||||
    static handle cast_impl(C *src, return_value_policy policy, handle parent) {
 | 
			
		||||
        object parent_object;
 | 
			
		||||
        bool writeable = false;
 | 
			
		||||
        switch (policy) {
 | 
			
		||||
            case return_value_policy::move:
 | 
			
		||||
                if (std::is_const<C>::value) {
 | 
			
		||||
                    pybind11_fail("Cannot move from a constant reference");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                src = Helper::alloc(std::move(*src));
 | 
			
		||||
 | 
			
		||||
                parent_object
 | 
			
		||||
                    = capsule(src, [](void *ptr) { Helper::free(reinterpret_cast<Type *>(ptr)); });
 | 
			
		||||
                writeable = true;
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case return_value_policy::take_ownership:
 | 
			
		||||
                if (std::is_const<C>::value) {
 | 
			
		||||
                    // This cast is ugly, and might be UB in some cases, but we don't have an
 | 
			
		||||
                    // alternative here as we must free that memory
 | 
			
		||||
                    Helper::free(const_cast<Type *>(src));
 | 
			
		||||
                    pybind11_fail("Cannot take ownership of a const reference");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                parent_object
 | 
			
		||||
                    = capsule(src, [](void *ptr) { Helper::free(reinterpret_cast<Type *>(ptr)); });
 | 
			
		||||
                writeable = true;
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case return_value_policy::copy:
 | 
			
		||||
                writeable = true;
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case return_value_policy::reference:
 | 
			
		||||
                parent_object = none();
 | 
			
		||||
                writeable = !std::is_const<C>::value;
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case return_value_policy::reference_internal:
 | 
			
		||||
                // Default should do the right thing
 | 
			
		||||
                if (!parent) {
 | 
			
		||||
                    pybind11_fail("Cannot use reference internal when there is no parent");
 | 
			
		||||
                }
 | 
			
		||||
                parent_object = reinterpret_borrow<object>(parent);
 | 
			
		||||
                writeable = !std::is_const<C>::value;
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            default:
 | 
			
		||||
                pybind11_fail("pybind11 bug in eigen.h, please file a bug report");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        auto result = array_t<typename Type::Scalar, compute_array_flag_from_tensor<Type>()>(
 | 
			
		||||
            convert_dsizes_to_vector(Helper::get_shape(*src)), src->data(), parent_object);
 | 
			
		||||
 | 
			
		||||
        if (!writeable) {
 | 
			
		||||
            array_proxy(result.ptr())->flags &= ~detail::npy_api::NPY_ARRAY_WRITEABLE_;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result.release();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename StoragePointerType,
 | 
			
		||||
          bool needs_writeable,
 | 
			
		||||
          enable_if_t<!needs_writeable, bool> = true>
 | 
			
		||||
StoragePointerType get_array_data_for_type(array &arr) {
 | 
			
		||||
#if EIGEN_VERSION_AT_LEAST(3, 4, 0)
 | 
			
		||||
    return reinterpret_cast<StoragePointerType>(arr.data());
 | 
			
		||||
#else
 | 
			
		||||
    // Handle Eigen bug
 | 
			
		||||
    return reinterpret_cast<StoragePointerType>(const_cast<void *>(arr.data()));
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename StoragePointerType,
 | 
			
		||||
          bool needs_writeable,
 | 
			
		||||
          enable_if_t<needs_writeable, bool> = true>
 | 
			
		||||
StoragePointerType get_array_data_for_type(array &arr) {
 | 
			
		||||
    return reinterpret_cast<StoragePointerType>(arr.mutable_data());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T, typename = void>
 | 
			
		||||
struct get_storage_pointer_type;
 | 
			
		||||
 | 
			
		||||
template <typename MapType>
 | 
			
		||||
struct get_storage_pointer_type<MapType, void_t<typename MapType::StoragePointerType>> {
 | 
			
		||||
    using SPT = typename MapType::StoragePointerType;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename MapType>
 | 
			
		||||
struct get_storage_pointer_type<MapType, void_t<typename MapType::PointerArgType>> {
 | 
			
		||||
    using SPT = typename MapType::PointerArgType;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename Type, int Options>
 | 
			
		||||
struct type_caster<Eigen::TensorMap<Type, Options>,
 | 
			
		||||
                   typename eigen_tensor_helper<remove_cv_t<Type>>::ValidType> {
 | 
			
		||||
    static_assert(!std::is_pointer<typename Type::Scalar>::value,
 | 
			
		||||
                  PYBIND11_EIGEN_MESSAGE_POINTER_TYPES_ARE_NOT_SUPPORTED);
 | 
			
		||||
    using MapType = Eigen::TensorMap<Type, Options>;
 | 
			
		||||
    using Helper = eigen_tensor_helper<remove_cv_t<Type>>;
 | 
			
		||||
 | 
			
		||||
    bool load(handle src, bool /*convert*/) {
 | 
			
		||||
        // Note that we have a lot more checks here as we want to make sure to avoid copies
 | 
			
		||||
        if (!isinstance<array>(src)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        auto arr = reinterpret_borrow<array>(src);
 | 
			
		||||
        if ((arr.flags() & compute_array_flag_from_tensor<Type>()) == 0) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!arr.dtype().is(dtype::of<typename Type::Scalar>())) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (arr.ndim() != Type::NumIndices) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        constexpr bool is_aligned = (Options & Eigen::Aligned) != 0;
 | 
			
		||||
 | 
			
		||||
        if (is_aligned && !is_tensor_aligned(arr.data())) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        auto shape = get_shape_for_array<typename Type::Index, Type::NumIndices>(arr);
 | 
			
		||||
 | 
			
		||||
        if (!Helper::is_correct_shape(shape)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (needs_writeable && !arr.writeable()) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        auto result = get_array_data_for_type<typename get_storage_pointer_type<MapType>::SPT,
 | 
			
		||||
                                              needs_writeable>(arr);
 | 
			
		||||
 | 
			
		||||
        value.reset(new MapType(std::move(result), std::move(shape)));
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static handle cast(MapType &&src, return_value_policy policy, handle parent) {
 | 
			
		||||
        return cast_impl(&src, policy, parent);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static handle cast(const MapType &&src, return_value_policy policy, handle parent) {
 | 
			
		||||
        return cast_impl(&src, policy, parent);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static handle cast(MapType &src, return_value_policy policy, handle parent) {
 | 
			
		||||
        if (policy == return_value_policy::automatic
 | 
			
		||||
            || policy == return_value_policy::automatic_reference) {
 | 
			
		||||
            policy = return_value_policy::copy;
 | 
			
		||||
        }
 | 
			
		||||
        return cast_impl(&src, policy, parent);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static handle cast(const MapType &src, return_value_policy policy, handle parent) {
 | 
			
		||||
        if (policy == return_value_policy::automatic
 | 
			
		||||
            || policy == return_value_policy::automatic_reference) {
 | 
			
		||||
            policy = return_value_policy::copy;
 | 
			
		||||
        }
 | 
			
		||||
        return cast(&src, policy, parent);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static handle cast(MapType *src, return_value_policy policy, handle parent) {
 | 
			
		||||
        if (policy == return_value_policy::automatic) {
 | 
			
		||||
            policy = return_value_policy::take_ownership;
 | 
			
		||||
        } else if (policy == return_value_policy::automatic_reference) {
 | 
			
		||||
            policy = return_value_policy::reference;
 | 
			
		||||
        }
 | 
			
		||||
        return cast_impl(src, policy, parent);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static handle cast(const MapType *src, return_value_policy policy, handle parent) {
 | 
			
		||||
        if (policy == return_value_policy::automatic) {
 | 
			
		||||
            policy = return_value_policy::take_ownership;
 | 
			
		||||
        } else if (policy == return_value_policy::automatic_reference) {
 | 
			
		||||
            policy = return_value_policy::reference;
 | 
			
		||||
        }
 | 
			
		||||
        return cast_impl(src, policy, parent);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <typename C>
 | 
			
		||||
    static handle cast_impl(C *src, return_value_policy policy, handle parent) {
 | 
			
		||||
        object parent_object;
 | 
			
		||||
        constexpr bool writeable = !std::is_const<C>::value;
 | 
			
		||||
        switch (policy) {
 | 
			
		||||
            case return_value_policy::reference:
 | 
			
		||||
                parent_object = none();
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case return_value_policy::reference_internal:
 | 
			
		||||
                // Default should do the right thing
 | 
			
		||||
                if (!parent) {
 | 
			
		||||
                    pybind11_fail("Cannot use reference internal when there is no parent");
 | 
			
		||||
                }
 | 
			
		||||
                parent_object = reinterpret_borrow<object>(parent);
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case return_value_policy::take_ownership:
 | 
			
		||||
                delete src;
 | 
			
		||||
                // fallthrough
 | 
			
		||||
            default:
 | 
			
		||||
                // move, take_ownership don't make any sense for a ref/map:
 | 
			
		||||
                pybind11_fail("Invalid return_value_policy for Eigen Map type, must be either "
 | 
			
		||||
                              "reference or reference_internal");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        auto result = array_t<typename Type::Scalar, compute_array_flag_from_tensor<Type>()>(
 | 
			
		||||
            convert_dsizes_to_vector(Helper::get_shape(*src)),
 | 
			
		||||
            src->data(),
 | 
			
		||||
            std::move(parent_object));
 | 
			
		||||
 | 
			
		||||
        if (!writeable) {
 | 
			
		||||
            array_proxy(result.ptr())->flags &= ~detail::npy_api::NPY_ARRAY_WRITEABLE_;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result.release();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if EIGEN_VERSION_AT_LEAST(3, 4, 0)
 | 
			
		||||
 | 
			
		||||
    static constexpr bool needs_writeable = !std::is_const<typename std::remove_pointer<
 | 
			
		||||
        typename get_storage_pointer_type<MapType>::SPT>::type>::value;
 | 
			
		||||
#else
 | 
			
		||||
    // Handle Eigen bug
 | 
			
		||||
    static constexpr bool needs_writeable = !std::is_const<Type>::value;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    // TODO: Move to std::optional once std::optional has more support
 | 
			
		||||
    std::unique_ptr<MapType> value;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    static constexpr auto name = get_tensor_descriptor<Type, true, needs_writeable>::value;
 | 
			
		||||
    explicit operator MapType *() { return value.get(); }
 | 
			
		||||
    explicit operator MapType &() { return *value; }
 | 
			
		||||
    explicit operator MapType &&() && { return std::move(*value); }
 | 
			
		||||
 | 
			
		||||
    template <typename T_>
 | 
			
		||||
    using cast_op_type = ::pybind11::detail::movable_cast_op_type<T_>;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_END(detail)
 | 
			
		||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
 | 
			
		||||
							
								
								
									
										316
									
								
								3rdparty/pybind11/include/pybind11/embed.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										316
									
								
								3rdparty/pybind11/include/pybind11/embed.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,316 @@
 | 
			
		||||
/*
 | 
			
		||||
    pybind11/embed.h: Support for embedding the interpreter
 | 
			
		||||
 | 
			
		||||
    Copyright (c) 2017 Wenzel Jakob <wenzel.jakob@epfl.ch>
 | 
			
		||||
 | 
			
		||||
    All rights reserved. Use of this source code is governed by a
 | 
			
		||||
    BSD-style license that can be found in the LICENSE file.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "pybind11.h"
 | 
			
		||||
#include "eval.h"
 | 
			
		||||
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#if defined(PYPY_VERSION)
 | 
			
		||||
#    error Embedding the interpreter is not supported with PyPy
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define PYBIND11_EMBEDDED_MODULE_IMPL(name)                                                       \
 | 
			
		||||
    extern "C" PyObject *pybind11_init_impl_##name();                                             \
 | 
			
		||||
    extern "C" PyObject *pybind11_init_impl_##name() { return pybind11_init_wrapper_##name(); }
 | 
			
		||||
 | 
			
		||||
/** \rst
 | 
			
		||||
    Add a new module to the table of builtins for the interpreter. Must be
 | 
			
		||||
    defined in global scope. The first macro parameter is the name of the
 | 
			
		||||
    module (without quotes). The second parameter is the variable which will
 | 
			
		||||
    be used as the interface to add functions and classes to the module.
 | 
			
		||||
 | 
			
		||||
    .. code-block:: cpp
 | 
			
		||||
 | 
			
		||||
        PYBIND11_EMBEDDED_MODULE(example, m) {
 | 
			
		||||
            // ... initialize functions and classes here
 | 
			
		||||
            m.def("foo", []() {
 | 
			
		||||
                return "Hello, World!";
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 \endrst */
 | 
			
		||||
#define PYBIND11_EMBEDDED_MODULE(name, variable)                                                  \
 | 
			
		||||
    static ::pybind11::module_::module_def PYBIND11_CONCAT(pybind11_module_def_, name);           \
 | 
			
		||||
    static void PYBIND11_CONCAT(pybind11_init_, name)(::pybind11::module_ &);                     \
 | 
			
		||||
    static PyObject PYBIND11_CONCAT(*pybind11_init_wrapper_, name)() {                            \
 | 
			
		||||
        auto m = ::pybind11::module_::create_extension_module(                                    \
 | 
			
		||||
            PYBIND11_TOSTRING(name), nullptr, &PYBIND11_CONCAT(pybind11_module_def_, name));      \
 | 
			
		||||
        try {                                                                                     \
 | 
			
		||||
            PYBIND11_CONCAT(pybind11_init_, name)(m);                                             \
 | 
			
		||||
            return m.ptr();                                                                       \
 | 
			
		||||
        }                                                                                         \
 | 
			
		||||
        PYBIND11_CATCH_INIT_EXCEPTIONS                                                            \
 | 
			
		||||
    }                                                                                             \
 | 
			
		||||
    PYBIND11_EMBEDDED_MODULE_IMPL(name)                                                           \
 | 
			
		||||
    ::pybind11::detail::embedded_module PYBIND11_CONCAT(pybind11_module_, name)(                  \
 | 
			
		||||
        PYBIND11_TOSTRING(name), PYBIND11_CONCAT(pybind11_init_impl_, name));                     \
 | 
			
		||||
    void PYBIND11_CONCAT(pybind11_init_, name)(::pybind11::module_                                \
 | 
			
		||||
                                               & variable) // NOLINT(bugprone-macro-parentheses)
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(detail)
 | 
			
		||||
 | 
			
		||||
/// Python 2.7/3.x compatible version of `PyImport_AppendInittab` and error checks.
 | 
			
		||||
struct embedded_module {
 | 
			
		||||
    using init_t = PyObject *(*) ();
 | 
			
		||||
    embedded_module(const char *name, init_t init) {
 | 
			
		||||
        if (Py_IsInitialized() != 0) {
 | 
			
		||||
            pybind11_fail("Can't add new modules after the interpreter has been initialized");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        auto result = PyImport_AppendInittab(name, init);
 | 
			
		||||
        if (result == -1) {
 | 
			
		||||
            pybind11_fail("Insufficient memory to add a new module");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct wide_char_arg_deleter {
 | 
			
		||||
    void operator()(wchar_t *ptr) const {
 | 
			
		||||
        // API docs: https://docs.python.org/3/c-api/sys.html#c.Py_DecodeLocale
 | 
			
		||||
        PyMem_RawFree(ptr);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
inline wchar_t *widen_chars(const char *safe_arg) {
 | 
			
		||||
    wchar_t *widened_arg = Py_DecodeLocale(safe_arg, nullptr);
 | 
			
		||||
    return widened_arg;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void precheck_interpreter() {
 | 
			
		||||
    if (Py_IsInitialized() != 0) {
 | 
			
		||||
        pybind11_fail("The interpreter is already running");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if !defined(PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX)
 | 
			
		||||
#    define PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX (0x03080000)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if PY_VERSION_HEX < PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX
 | 
			
		||||
inline void initialize_interpreter_pre_pyconfig(bool init_signal_handlers,
 | 
			
		||||
                                                int argc,
 | 
			
		||||
                                                const char *const *argv,
 | 
			
		||||
                                                bool add_program_dir_to_path) {
 | 
			
		||||
    detail::precheck_interpreter();
 | 
			
		||||
    Py_InitializeEx(init_signal_handlers ? 1 : 0);
 | 
			
		||||
#    if defined(WITH_THREAD) && PY_VERSION_HEX < 0x03070000
 | 
			
		||||
    PyEval_InitThreads();
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
    // Before it was special-cased in python 3.8, passing an empty or null argv
 | 
			
		||||
    // caused a segfault, so we have to reimplement the special case ourselves.
 | 
			
		||||
    bool special_case = (argv == nullptr || argc <= 0);
 | 
			
		||||
 | 
			
		||||
    const char *const empty_argv[]{"\0"};
 | 
			
		||||
    const char *const *safe_argv = special_case ? empty_argv : argv;
 | 
			
		||||
    if (special_case) {
 | 
			
		||||
        argc = 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    auto argv_size = static_cast<size_t>(argc);
 | 
			
		||||
    // SetArgv* on python 3 takes wchar_t, so we have to convert.
 | 
			
		||||
    std::unique_ptr<wchar_t *[]> widened_argv(new wchar_t *[argv_size]);
 | 
			
		||||
    std::vector<std::unique_ptr<wchar_t[], detail::wide_char_arg_deleter>> widened_argv_entries;
 | 
			
		||||
    widened_argv_entries.reserve(argv_size);
 | 
			
		||||
    for (size_t ii = 0; ii < argv_size; ++ii) {
 | 
			
		||||
        widened_argv_entries.emplace_back(detail::widen_chars(safe_argv[ii]));
 | 
			
		||||
        if (!widened_argv_entries.back()) {
 | 
			
		||||
            // A null here indicates a character-encoding failure or the python
 | 
			
		||||
            // interpreter out of memory. Give up.
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        widened_argv[ii] = widened_argv_entries.back().get();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    auto *pysys_argv = widened_argv.get();
 | 
			
		||||
 | 
			
		||||
    PySys_SetArgvEx(argc, pysys_argv, static_cast<int>(add_program_dir_to_path));
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_END(detail)
 | 
			
		||||
 | 
			
		||||
#if PY_VERSION_HEX >= PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX
 | 
			
		||||
inline void initialize_interpreter(PyConfig *config,
 | 
			
		||||
                                   int argc = 0,
 | 
			
		||||
                                   const char *const *argv = nullptr,
 | 
			
		||||
                                   bool add_program_dir_to_path = true) {
 | 
			
		||||
    detail::precheck_interpreter();
 | 
			
		||||
    PyStatus status = PyConfig_SetBytesArgv(config, argc, const_cast<char *const *>(argv));
 | 
			
		||||
    if (PyStatus_Exception(status) != 0) {
 | 
			
		||||
        // A failure here indicates a character-encoding failure or the python
 | 
			
		||||
        // interpreter out of memory. Give up.
 | 
			
		||||
        PyConfig_Clear(config);
 | 
			
		||||
        throw std::runtime_error(PyStatus_IsError(status) != 0 ? status.err_msg
 | 
			
		||||
                                                               : "Failed to prepare CPython");
 | 
			
		||||
    }
 | 
			
		||||
    status = Py_InitializeFromConfig(config);
 | 
			
		||||
    if (PyStatus_Exception(status) != 0) {
 | 
			
		||||
        PyConfig_Clear(config);
 | 
			
		||||
        throw std::runtime_error(PyStatus_IsError(status) != 0 ? status.err_msg
 | 
			
		||||
                                                               : "Failed to init CPython");
 | 
			
		||||
    }
 | 
			
		||||
    if (add_program_dir_to_path) {
 | 
			
		||||
        PyRun_SimpleString("import sys, os.path; "
 | 
			
		||||
                           "sys.path.insert(0, "
 | 
			
		||||
                           "os.path.abspath(os.path.dirname(sys.argv[0])) "
 | 
			
		||||
                           "if sys.argv and os.path.exists(sys.argv[0]) else '')");
 | 
			
		||||
    }
 | 
			
		||||
    PyConfig_Clear(config);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/** \rst
 | 
			
		||||
    Initialize the Python interpreter. No other pybind11 or CPython API functions can be
 | 
			
		||||
    called before this is done; with the exception of `PYBIND11_EMBEDDED_MODULE`. The
 | 
			
		||||
    optional `init_signal_handlers` parameter can be used to skip the registration of
 | 
			
		||||
    signal handlers (see the `Python documentation`_ for details). Calling this function
 | 
			
		||||
    again after the interpreter has already been initialized is a fatal error.
 | 
			
		||||
 | 
			
		||||
    If initializing the Python interpreter fails, then the program is terminated.  (This
 | 
			
		||||
    is controlled by the CPython runtime and is an exception to pybind11's normal behavior
 | 
			
		||||
    of throwing exceptions on errors.)
 | 
			
		||||
 | 
			
		||||
    The remaining optional parameters, `argc`, `argv`, and `add_program_dir_to_path` are
 | 
			
		||||
    used to populate ``sys.argv`` and ``sys.path``.
 | 
			
		||||
    See the |PySys_SetArgvEx documentation|_ for details.
 | 
			
		||||
 | 
			
		||||
    .. _Python documentation: https://docs.python.org/3/c-api/init.html#c.Py_InitializeEx
 | 
			
		||||
    .. |PySys_SetArgvEx documentation| replace:: ``PySys_SetArgvEx`` documentation
 | 
			
		||||
    .. _PySys_SetArgvEx documentation: https://docs.python.org/3/c-api/init.html#c.PySys_SetArgvEx
 | 
			
		||||
 \endrst */
 | 
			
		||||
inline void initialize_interpreter(bool init_signal_handlers = true,
 | 
			
		||||
                                   int argc = 0,
 | 
			
		||||
                                   const char *const *argv = nullptr,
 | 
			
		||||
                                   bool add_program_dir_to_path = true) {
 | 
			
		||||
#if PY_VERSION_HEX < PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX
 | 
			
		||||
    detail::initialize_interpreter_pre_pyconfig(
 | 
			
		||||
        init_signal_handlers, argc, argv, add_program_dir_to_path);
 | 
			
		||||
#else
 | 
			
		||||
    PyConfig config;
 | 
			
		||||
    PyConfig_InitPythonConfig(&config);
 | 
			
		||||
    // See PR #4473 for background
 | 
			
		||||
    config.parse_argv = 0;
 | 
			
		||||
 | 
			
		||||
    config.install_signal_handlers = init_signal_handlers ? 1 : 0;
 | 
			
		||||
    initialize_interpreter(&config, argc, argv, add_program_dir_to_path);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** \rst
 | 
			
		||||
    Shut down the Python interpreter. No pybind11 or CPython API functions can be called
 | 
			
		||||
    after this. In addition, pybind11 objects must not outlive the interpreter:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: cpp
 | 
			
		||||
 | 
			
		||||
        { // BAD
 | 
			
		||||
            py::initialize_interpreter();
 | 
			
		||||
            auto hello = py::str("Hello, World!");
 | 
			
		||||
            py::finalize_interpreter();
 | 
			
		||||
        } // <-- BOOM, hello's destructor is called after interpreter shutdown
 | 
			
		||||
 | 
			
		||||
        { // GOOD
 | 
			
		||||
            py::initialize_interpreter();
 | 
			
		||||
            { // scoped
 | 
			
		||||
                auto hello = py::str("Hello, World!");
 | 
			
		||||
            } // <-- OK, hello is cleaned up properly
 | 
			
		||||
            py::finalize_interpreter();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        { // BETTER
 | 
			
		||||
            py::scoped_interpreter guard{};
 | 
			
		||||
            auto hello = py::str("Hello, World!");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    .. warning::
 | 
			
		||||
 | 
			
		||||
        The interpreter can be restarted by calling `initialize_interpreter` again.
 | 
			
		||||
        Modules created using pybind11 can be safely re-initialized. However, Python
 | 
			
		||||
        itself cannot completely unload binary extension modules and there are several
 | 
			
		||||
        caveats with regard to interpreter restarting. All the details can be found
 | 
			
		||||
        in the CPython documentation. In short, not all interpreter memory may be
 | 
			
		||||
        freed, either due to reference cycles or user-created global data.
 | 
			
		||||
 | 
			
		||||
 \endrst */
 | 
			
		||||
inline void finalize_interpreter() {
 | 
			
		||||
    // Get the internals pointer (without creating it if it doesn't exist).  It's possible for the
 | 
			
		||||
    // internals to be created during Py_Finalize() (e.g. if a py::capsule calls `get_internals()`
 | 
			
		||||
    // during destruction), so we get the pointer-pointer here and check it after Py_Finalize().
 | 
			
		||||
    detail::internals **internals_ptr_ptr = detail::get_internals_pp();
 | 
			
		||||
    // It could also be stashed in state_dict, so look there too:
 | 
			
		||||
    if (object internals_obj
 | 
			
		||||
        = get_internals_obj_from_state_dict(detail::get_python_state_dict())) {
 | 
			
		||||
        internals_ptr_ptr = detail::get_internals_pp_from_capsule(internals_obj);
 | 
			
		||||
    }
 | 
			
		||||
    // Local internals contains data managed by the current interpreter, so we must clear them to
 | 
			
		||||
    // avoid undefined behaviors when initializing another interpreter
 | 
			
		||||
    detail::get_local_internals().registered_types_cpp.clear();
 | 
			
		||||
    detail::get_local_internals().registered_exception_translators.clear();
 | 
			
		||||
 | 
			
		||||
    Py_Finalize();
 | 
			
		||||
 | 
			
		||||
    if (internals_ptr_ptr) {
 | 
			
		||||
        delete *internals_ptr_ptr;
 | 
			
		||||
        *internals_ptr_ptr = nullptr;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** \rst
 | 
			
		||||
    Scope guard version of `initialize_interpreter` and `finalize_interpreter`.
 | 
			
		||||
    This a move-only guard and only a single instance can exist.
 | 
			
		||||
 | 
			
		||||
    See `initialize_interpreter` for a discussion of its constructor arguments.
 | 
			
		||||
 | 
			
		||||
    .. code-block:: cpp
 | 
			
		||||
 | 
			
		||||
        #include <pybind11/embed.h>
 | 
			
		||||
 | 
			
		||||
        int main() {
 | 
			
		||||
            py::scoped_interpreter guard{};
 | 
			
		||||
            py::print(Hello, World!);
 | 
			
		||||
        } // <-- interpreter shutdown
 | 
			
		||||
 \endrst */
 | 
			
		||||
class scoped_interpreter {
 | 
			
		||||
public:
 | 
			
		||||
    explicit scoped_interpreter(bool init_signal_handlers = true,
 | 
			
		||||
                                int argc = 0,
 | 
			
		||||
                                const char *const *argv = nullptr,
 | 
			
		||||
                                bool add_program_dir_to_path = true) {
 | 
			
		||||
        initialize_interpreter(init_signal_handlers, argc, argv, add_program_dir_to_path);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if PY_VERSION_HEX >= PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX
 | 
			
		||||
    explicit scoped_interpreter(PyConfig *config,
 | 
			
		||||
                                int argc = 0,
 | 
			
		||||
                                const char *const *argv = nullptr,
 | 
			
		||||
                                bool add_program_dir_to_path = true) {
 | 
			
		||||
        initialize_interpreter(config, argc, argv, add_program_dir_to_path);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    scoped_interpreter(const scoped_interpreter &) = delete;
 | 
			
		||||
    scoped_interpreter(scoped_interpreter &&other) noexcept { other.is_valid = false; }
 | 
			
		||||
    scoped_interpreter &operator=(const scoped_interpreter &) = delete;
 | 
			
		||||
    scoped_interpreter &operator=(scoped_interpreter &&) = delete;
 | 
			
		||||
 | 
			
		||||
    ~scoped_interpreter() {
 | 
			
		||||
        if (is_valid) {
 | 
			
		||||
            finalize_interpreter();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    bool is_valid = true;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
 | 
			
		||||
							
								
								
									
										156
									
								
								3rdparty/pybind11/include/pybind11/eval.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								3rdparty/pybind11/include/pybind11/eval.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,156 @@
 | 
			
		||||
/*
 | 
			
		||||
    pybind11/eval.h: Support for evaluating Python expressions and statements
 | 
			
		||||
    from strings and files
 | 
			
		||||
 | 
			
		||||
    Copyright (c) 2016 Klemens Morgenstern <klemens.morgenstern@ed-chemnitz.de> and
 | 
			
		||||
                       Wenzel Jakob <wenzel.jakob@epfl.ch>
 | 
			
		||||
 | 
			
		||||
    All rights reserved. Use of this source code is governed by a
 | 
			
		||||
    BSD-style license that can be found in the LICENSE file.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "pybind11.h"
 | 
			
		||||
 | 
			
		||||
#include <utility>
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(detail)
 | 
			
		||||
 | 
			
		||||
inline void ensure_builtins_in_globals(object &global) {
 | 
			
		||||
#if defined(PYPY_VERSION) || PY_VERSION_HEX < 0x03080000
 | 
			
		||||
    // Running exec and eval adds `builtins` module under `__builtins__` key to
 | 
			
		||||
    // globals if not yet present.  Python 3.8 made PyRun_String behave
 | 
			
		||||
    // similarly. Let's also do that for older versions, for consistency. This
 | 
			
		||||
    // was missing from PyPy3.8 7.3.7.
 | 
			
		||||
    if (!global.contains("__builtins__"))
 | 
			
		||||
        global["__builtins__"] = module_::import(PYBIND11_BUILTINS_MODULE);
 | 
			
		||||
#else
 | 
			
		||||
    (void) global;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_END(detail)
 | 
			
		||||
 | 
			
		||||
enum eval_mode {
 | 
			
		||||
    /// Evaluate a string containing an isolated expression
 | 
			
		||||
    eval_expr,
 | 
			
		||||
 | 
			
		||||
    /// Evaluate a string containing a single statement. Returns \c none
 | 
			
		||||
    eval_single_statement,
 | 
			
		||||
 | 
			
		||||
    /// Evaluate a string containing a sequence of statement. Returns \c none
 | 
			
		||||
    eval_statements
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <eval_mode mode = eval_expr>
 | 
			
		||||
object eval(const str &expr, object global = globals(), object local = object()) {
 | 
			
		||||
    if (!local) {
 | 
			
		||||
        local = global;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    detail::ensure_builtins_in_globals(global);
 | 
			
		||||
 | 
			
		||||
    /* PyRun_String does not accept a PyObject / encoding specifier,
 | 
			
		||||
       this seems to be the only alternative */
 | 
			
		||||
    std::string buffer = "# -*- coding: utf-8 -*-\n" + (std::string) expr;
 | 
			
		||||
 | 
			
		||||
    int start = 0;
 | 
			
		||||
    switch (mode) {
 | 
			
		||||
        case eval_expr:
 | 
			
		||||
            start = Py_eval_input;
 | 
			
		||||
            break;
 | 
			
		||||
        case eval_single_statement:
 | 
			
		||||
            start = Py_single_input;
 | 
			
		||||
            break;
 | 
			
		||||
        case eval_statements:
 | 
			
		||||
            start = Py_file_input;
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            pybind11_fail("invalid evaluation mode");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    PyObject *result = PyRun_String(buffer.c_str(), start, global.ptr(), local.ptr());
 | 
			
		||||
    if (!result) {
 | 
			
		||||
        throw error_already_set();
 | 
			
		||||
    }
 | 
			
		||||
    return reinterpret_steal<object>(result);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <eval_mode mode = eval_expr, size_t N>
 | 
			
		||||
object eval(const char (&s)[N], object global = globals(), object local = object()) {
 | 
			
		||||
    /* Support raw string literals by removing common leading whitespace */
 | 
			
		||||
    auto expr = (s[0] == '\n') ? str(module_::import("textwrap").attr("dedent")(s)) : str(s);
 | 
			
		||||
    return eval<mode>(expr, std::move(global), std::move(local));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void exec(const str &expr, object global = globals(), object local = object()) {
 | 
			
		||||
    eval<eval_statements>(expr, std::move(global), std::move(local));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <size_t N>
 | 
			
		||||
void exec(const char (&s)[N], object global = globals(), object local = object()) {
 | 
			
		||||
    eval<eval_statements>(s, std::move(global), std::move(local));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined(PYPY_VERSION)
 | 
			
		||||
template <eval_mode mode = eval_statements>
 | 
			
		||||
object eval_file(str, object, object) {
 | 
			
		||||
    pybind11_fail("eval_file not supported in PyPy3. Use eval");
 | 
			
		||||
}
 | 
			
		||||
template <eval_mode mode = eval_statements>
 | 
			
		||||
object eval_file(str, object) {
 | 
			
		||||
    pybind11_fail("eval_file not supported in PyPy3. Use eval");
 | 
			
		||||
}
 | 
			
		||||
template <eval_mode mode = eval_statements>
 | 
			
		||||
object eval_file(str) {
 | 
			
		||||
    pybind11_fail("eval_file not supported in PyPy3. Use eval");
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
template <eval_mode mode = eval_statements>
 | 
			
		||||
object eval_file(str fname, object global = globals(), object local = object()) {
 | 
			
		||||
    if (!local) {
 | 
			
		||||
        local = global;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    detail::ensure_builtins_in_globals(global);
 | 
			
		||||
 | 
			
		||||
    int start = 0;
 | 
			
		||||
    switch (mode) {
 | 
			
		||||
        case eval_expr:
 | 
			
		||||
            start = Py_eval_input;
 | 
			
		||||
            break;
 | 
			
		||||
        case eval_single_statement:
 | 
			
		||||
            start = Py_single_input;
 | 
			
		||||
            break;
 | 
			
		||||
        case eval_statements:
 | 
			
		||||
            start = Py_file_input;
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            pybind11_fail("invalid evaluation mode");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int closeFile = 1;
 | 
			
		||||
    std::string fname_str = (std::string) fname;
 | 
			
		||||
    FILE *f = _Py_fopen_obj(fname.ptr(), "r");
 | 
			
		||||
    if (!f) {
 | 
			
		||||
        PyErr_Clear();
 | 
			
		||||
        pybind11_fail("File \"" + fname_str + "\" could not be opened!");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!global.contains("__file__")) {
 | 
			
		||||
        global["__file__"] = std::move(fname);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    PyObject *result
 | 
			
		||||
        = PyRun_FileEx(f, fname_str.c_str(), start, global.ptr(), local.ptr(), closeFile);
 | 
			
		||||
 | 
			
		||||
    if (!result) {
 | 
			
		||||
        throw error_already_set();
 | 
			
		||||
    }
 | 
			
		||||
    return reinterpret_steal<object>(result);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
 | 
			
		||||
							
								
								
									
										137
									
								
								3rdparty/pybind11/include/pybind11/functional.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								3rdparty/pybind11/include/pybind11/functional.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,137 @@
 | 
			
		||||
/*
 | 
			
		||||
    pybind11/functional.h: std::function<> support
 | 
			
		||||
 | 
			
		||||
    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
 | 
			
		||||
 | 
			
		||||
    All rights reserved. Use of this source code is governed by a
 | 
			
		||||
    BSD-style license that can be found in the LICENSE file.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "pybind11.h"
 | 
			
		||||
 | 
			
		||||
#include <functional>
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(detail)
 | 
			
		||||
 | 
			
		||||
template <typename Return, typename... Args>
 | 
			
		||||
struct type_caster<std::function<Return(Args...)>> {
 | 
			
		||||
    using type = std::function<Return(Args...)>;
 | 
			
		||||
    using retval_type = conditional_t<std::is_same<Return, void>::value, void_type, Return>;
 | 
			
		||||
    using function_type = Return (*)(Args...);
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    bool load(handle src, bool convert) {
 | 
			
		||||
        if (src.is_none()) {
 | 
			
		||||
            // Defer accepting None to other overloads (if we aren't in convert mode):
 | 
			
		||||
            if (!convert) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!isinstance<function>(src)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        auto func = reinterpret_borrow<function>(src);
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
           When passing a C++ function as an argument to another C++
 | 
			
		||||
           function via Python, every function call would normally involve
 | 
			
		||||
           a full C++ -> Python -> C++ roundtrip, which can be prohibitive.
 | 
			
		||||
           Here, we try to at least detect the case where the function is
 | 
			
		||||
           stateless (i.e. function pointer or lambda function without
 | 
			
		||||
           captured variables), in which case the roundtrip can be avoided.
 | 
			
		||||
         */
 | 
			
		||||
        if (auto cfunc = func.cpp_function()) {
 | 
			
		||||
            auto *cfunc_self = PyCFunction_GET_SELF(cfunc.ptr());
 | 
			
		||||
            if (cfunc_self == nullptr) {
 | 
			
		||||
                PyErr_Clear();
 | 
			
		||||
            } else if (isinstance<capsule>(cfunc_self)) {
 | 
			
		||||
                auto c = reinterpret_borrow<capsule>(cfunc_self);
 | 
			
		||||
 | 
			
		||||
                function_record *rec = nullptr;
 | 
			
		||||
                // Check that we can safely reinterpret the capsule into a function_record
 | 
			
		||||
                if (detail::is_function_record_capsule(c)) {
 | 
			
		||||
                    rec = c.get_pointer<function_record>();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                while (rec != nullptr) {
 | 
			
		||||
                    if (rec->is_stateless
 | 
			
		||||
                        && same_type(typeid(function_type),
 | 
			
		||||
                                     *reinterpret_cast<const std::type_info *>(rec->data[1]))) {
 | 
			
		||||
                        struct capture {
 | 
			
		||||
                            function_type f;
 | 
			
		||||
                        };
 | 
			
		||||
                        value = ((capture *) &rec->data)->f;
 | 
			
		||||
                        return true;
 | 
			
		||||
                    }
 | 
			
		||||
                    rec = rec->next;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            // PYPY segfaults here when passing builtin function like sum.
 | 
			
		||||
            // Raising an fail exception here works to prevent the segfault, but only on gcc.
 | 
			
		||||
            // See PR #1413 for full details
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // ensure GIL is held during functor destruction
 | 
			
		||||
        struct func_handle {
 | 
			
		||||
            function f;
 | 
			
		||||
#if !(defined(_MSC_VER) && _MSC_VER == 1916 && defined(PYBIND11_CPP17))
 | 
			
		||||
            // This triggers a syntax error under very special conditions (very weird indeed).
 | 
			
		||||
            explicit
 | 
			
		||||
#endif
 | 
			
		||||
                func_handle(function &&f_) noexcept
 | 
			
		||||
                : f(std::move(f_)) {
 | 
			
		||||
            }
 | 
			
		||||
            func_handle(const func_handle &f_) { operator=(f_); }
 | 
			
		||||
            func_handle &operator=(const func_handle &f_) {
 | 
			
		||||
                gil_scoped_acquire acq;
 | 
			
		||||
                f = f_.f;
 | 
			
		||||
                return *this;
 | 
			
		||||
            }
 | 
			
		||||
            ~func_handle() {
 | 
			
		||||
                gil_scoped_acquire acq;
 | 
			
		||||
                function kill_f(std::move(f));
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        // to emulate 'move initialization capture' in C++11
 | 
			
		||||
        struct func_wrapper {
 | 
			
		||||
            func_handle hfunc;
 | 
			
		||||
            explicit func_wrapper(func_handle &&hf) noexcept : hfunc(std::move(hf)) {}
 | 
			
		||||
            Return operator()(Args... args) const {
 | 
			
		||||
                gil_scoped_acquire acq;
 | 
			
		||||
                // casts the returned object as a rvalue to the return type
 | 
			
		||||
                return hfunc.f(std::forward<Args>(args)...).template cast<Return>();
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        value = func_wrapper(func_handle(std::move(func)));
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <typename Func>
 | 
			
		||||
    static handle cast(Func &&f_, return_value_policy policy, handle /* parent */) {
 | 
			
		||||
        if (!f_) {
 | 
			
		||||
            return none().release();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        auto result = f_.template target<function_type>();
 | 
			
		||||
        if (result) {
 | 
			
		||||
            return cpp_function(*result, policy).release();
 | 
			
		||||
        }
 | 
			
		||||
        return cpp_function(std::forward<Func>(f_), policy).release();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    PYBIND11_TYPE_CASTER(type,
 | 
			
		||||
                         const_name("Callable[[") + concat(make_caster<Args>::name...)
 | 
			
		||||
                             + const_name("], ") + make_caster<retval_type>::name
 | 
			
		||||
                             + const_name("]"));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_END(detail)
 | 
			
		||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
 | 
			
		||||
							
								
								
									
										239
									
								
								3rdparty/pybind11/include/pybind11/gil.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										239
									
								
								3rdparty/pybind11/include/pybind11/gil.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,239 @@
 | 
			
		||||
/*
 | 
			
		||||
    pybind11/gil.h: RAII helpers for managing the GIL
 | 
			
		||||
 | 
			
		||||
    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
 | 
			
		||||
 | 
			
		||||
    All rights reserved. Use of this source code is governed by a
 | 
			
		||||
    BSD-style license that can be found in the LICENSE file.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "detail/common.h"
 | 
			
		||||
 | 
			
		||||
#if defined(WITH_THREAD) && !defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)
 | 
			
		||||
#    include "detail/internals.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(detail)
 | 
			
		||||
 | 
			
		||||
// forward declarations
 | 
			
		||||
PyThreadState *get_thread_state_unchecked();
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_END(detail)
 | 
			
		||||
 | 
			
		||||
#if defined(WITH_THREAD)
 | 
			
		||||
 | 
			
		||||
#    if !defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)
 | 
			
		||||
 | 
			
		||||
/* The functions below essentially reproduce the PyGILState_* API using a RAII
 | 
			
		||||
 * pattern, but there are a few important differences:
 | 
			
		||||
 *
 | 
			
		||||
 * 1. When acquiring the GIL from an non-main thread during the finalization
 | 
			
		||||
 *    phase, the GILState API blindly terminates the calling thread, which
 | 
			
		||||
 *    is often not what is wanted. This API does not do this.
 | 
			
		||||
 *
 | 
			
		||||
 * 2. The gil_scoped_release function can optionally cut the relationship
 | 
			
		||||
 *    of a PyThreadState and its associated thread, which allows moving it to
 | 
			
		||||
 *    another thread (this is a fairly rare/advanced use case).
 | 
			
		||||
 *
 | 
			
		||||
 * 3. The reference count of an acquired thread state can be controlled. This
 | 
			
		||||
 *    can be handy to prevent cases where callbacks issued from an external
 | 
			
		||||
 *    thread would otherwise constantly construct and destroy thread state data
 | 
			
		||||
 *    structures.
 | 
			
		||||
 *
 | 
			
		||||
 * See the Python bindings of NanoGUI (http://github.com/wjakob/nanogui) for an
 | 
			
		||||
 * example which uses features 2 and 3 to migrate the Python thread of
 | 
			
		||||
 * execution to another thread (to run the event loop on the original thread,
 | 
			
		||||
 * in this case).
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
class gil_scoped_acquire {
 | 
			
		||||
public:
 | 
			
		||||
    PYBIND11_NOINLINE gil_scoped_acquire() {
 | 
			
		||||
        auto &internals = detail::get_internals();
 | 
			
		||||
        tstate = (PyThreadState *) PYBIND11_TLS_GET_VALUE(internals.tstate);
 | 
			
		||||
 | 
			
		||||
        if (!tstate) {
 | 
			
		||||
            /* Check if the GIL was acquired using the PyGILState_* API instead (e.g. if
 | 
			
		||||
               calling from a Python thread). Since we use a different key, this ensures
 | 
			
		||||
               we don't create a new thread state and deadlock in PyEval_AcquireThread
 | 
			
		||||
               below. Note we don't save this state with internals.tstate, since we don't
 | 
			
		||||
               create it we would fail to clear it (its reference count should be > 0). */
 | 
			
		||||
            tstate = PyGILState_GetThisThreadState();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!tstate) {
 | 
			
		||||
            tstate = PyThreadState_New(internals.istate);
 | 
			
		||||
#        if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
 | 
			
		||||
            if (!tstate) {
 | 
			
		||||
                pybind11_fail("scoped_acquire: could not create thread state!");
 | 
			
		||||
            }
 | 
			
		||||
#        endif
 | 
			
		||||
            tstate->gilstate_counter = 0;
 | 
			
		||||
            PYBIND11_TLS_REPLACE_VALUE(internals.tstate, tstate);
 | 
			
		||||
        } else {
 | 
			
		||||
            release = detail::get_thread_state_unchecked() != tstate;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (release) {
 | 
			
		||||
            PyEval_AcquireThread(tstate);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        inc_ref();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    gil_scoped_acquire(const gil_scoped_acquire &) = delete;
 | 
			
		||||
    gil_scoped_acquire &operator=(const gil_scoped_acquire &) = delete;
 | 
			
		||||
 | 
			
		||||
    void inc_ref() { ++tstate->gilstate_counter; }
 | 
			
		||||
 | 
			
		||||
    PYBIND11_NOINLINE void dec_ref() {
 | 
			
		||||
        --tstate->gilstate_counter;
 | 
			
		||||
#        if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
 | 
			
		||||
        if (detail::get_thread_state_unchecked() != tstate) {
 | 
			
		||||
            pybind11_fail("scoped_acquire::dec_ref(): thread state must be current!");
 | 
			
		||||
        }
 | 
			
		||||
        if (tstate->gilstate_counter < 0) {
 | 
			
		||||
            pybind11_fail("scoped_acquire::dec_ref(): reference count underflow!");
 | 
			
		||||
        }
 | 
			
		||||
#        endif
 | 
			
		||||
        if (tstate->gilstate_counter == 0) {
 | 
			
		||||
#        if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
 | 
			
		||||
            if (!release) {
 | 
			
		||||
                pybind11_fail("scoped_acquire::dec_ref(): internal error!");
 | 
			
		||||
            }
 | 
			
		||||
#        endif
 | 
			
		||||
            PyThreadState_Clear(tstate);
 | 
			
		||||
            if (active) {
 | 
			
		||||
                PyThreadState_DeleteCurrent();
 | 
			
		||||
            }
 | 
			
		||||
            PYBIND11_TLS_DELETE_VALUE(detail::get_internals().tstate);
 | 
			
		||||
            release = false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// This method will disable the PyThreadState_DeleteCurrent call and the
 | 
			
		||||
    /// GIL won't be acquired. This method should be used if the interpreter
 | 
			
		||||
    /// could be shutting down when this is called, as thread deletion is not
 | 
			
		||||
    /// allowed during shutdown. Check _Py_IsFinalizing() on Python 3.7+, and
 | 
			
		||||
    /// protect subsequent code.
 | 
			
		||||
    PYBIND11_NOINLINE void disarm() { active = false; }
 | 
			
		||||
 | 
			
		||||
    PYBIND11_NOINLINE ~gil_scoped_acquire() {
 | 
			
		||||
        dec_ref();
 | 
			
		||||
        if (release) {
 | 
			
		||||
            PyEval_SaveThread();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    PyThreadState *tstate = nullptr;
 | 
			
		||||
    bool release = true;
 | 
			
		||||
    bool active = true;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class gil_scoped_release {
 | 
			
		||||
public:
 | 
			
		||||
    explicit gil_scoped_release(bool disassoc = false) : disassoc(disassoc) {
 | 
			
		||||
        // `get_internals()` must be called here unconditionally in order to initialize
 | 
			
		||||
        // `internals.tstate` for subsequent `gil_scoped_acquire` calls. Otherwise, an
 | 
			
		||||
        // initialization race could occur as multiple threads try `gil_scoped_acquire`.
 | 
			
		||||
        auto &internals = detail::get_internals();
 | 
			
		||||
        // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)
 | 
			
		||||
        tstate = PyEval_SaveThread();
 | 
			
		||||
        if (disassoc) {
 | 
			
		||||
            // Python >= 3.7 can remove this, it's an int before 3.7
 | 
			
		||||
            // NOLINTNEXTLINE(readability-qualified-auto)
 | 
			
		||||
            auto key = internals.tstate;
 | 
			
		||||
            PYBIND11_TLS_DELETE_VALUE(key);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    gil_scoped_release(const gil_scoped_release &) = delete;
 | 
			
		||||
    gil_scoped_release &operator=(const gil_scoped_release &) = delete;
 | 
			
		||||
 | 
			
		||||
    /// This method will disable the PyThreadState_DeleteCurrent call and the
 | 
			
		||||
    /// GIL won't be acquired. This method should be used if the interpreter
 | 
			
		||||
    /// could be shutting down when this is called, as thread deletion is not
 | 
			
		||||
    /// allowed during shutdown. Check _Py_IsFinalizing() on Python 3.7+, and
 | 
			
		||||
    /// protect subsequent code.
 | 
			
		||||
    PYBIND11_NOINLINE void disarm() { active = false; }
 | 
			
		||||
 | 
			
		||||
    ~gil_scoped_release() {
 | 
			
		||||
        if (!tstate) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        // `PyEval_RestoreThread()` should not be called if runtime is finalizing
 | 
			
		||||
        if (active) {
 | 
			
		||||
            PyEval_RestoreThread(tstate);
 | 
			
		||||
        }
 | 
			
		||||
        if (disassoc) {
 | 
			
		||||
            // Python >= 3.7 can remove this, it's an int before 3.7
 | 
			
		||||
            // NOLINTNEXTLINE(readability-qualified-auto)
 | 
			
		||||
            auto key = detail::get_internals().tstate;
 | 
			
		||||
            PYBIND11_TLS_REPLACE_VALUE(key, tstate);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    PyThreadState *tstate;
 | 
			
		||||
    bool disassoc;
 | 
			
		||||
    bool active = true;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#    else // PYBIND11_SIMPLE_GIL_MANAGEMENT
 | 
			
		||||
 | 
			
		||||
class gil_scoped_acquire {
 | 
			
		||||
    PyGILState_STATE state;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    gil_scoped_acquire() : state{PyGILState_Ensure()} {}
 | 
			
		||||
    gil_scoped_acquire(const gil_scoped_acquire &) = delete;
 | 
			
		||||
    gil_scoped_acquire &operator=(const gil_scoped_acquire &) = delete;
 | 
			
		||||
    ~gil_scoped_acquire() { PyGILState_Release(state); }
 | 
			
		||||
    void disarm() {}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class gil_scoped_release {
 | 
			
		||||
    PyThreadState *state;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    gil_scoped_release() : state{PyEval_SaveThread()} {}
 | 
			
		||||
    gil_scoped_release(const gil_scoped_release &) = delete;
 | 
			
		||||
    gil_scoped_release &operator=(const gil_scoped_release &) = delete;
 | 
			
		||||
    ~gil_scoped_release() { PyEval_RestoreThread(state); }
 | 
			
		||||
    void disarm() {}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#    endif // PYBIND11_SIMPLE_GIL_MANAGEMENT
 | 
			
		||||
 | 
			
		||||
#else // WITH_THREAD
 | 
			
		||||
 | 
			
		||||
class gil_scoped_acquire {
 | 
			
		||||
public:
 | 
			
		||||
    gil_scoped_acquire() {
 | 
			
		||||
        // Trick to suppress `unused variable` error messages (at call sites).
 | 
			
		||||
        (void) (this != (this + 1));
 | 
			
		||||
    }
 | 
			
		||||
    gil_scoped_acquire(const gil_scoped_acquire &) = delete;
 | 
			
		||||
    gil_scoped_acquire &operator=(const gil_scoped_acquire &) = delete;
 | 
			
		||||
    void disarm() {}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class gil_scoped_release {
 | 
			
		||||
public:
 | 
			
		||||
    gil_scoped_release() {
 | 
			
		||||
        // Trick to suppress `unused variable` error messages (at call sites).
 | 
			
		||||
        (void) (this != (this + 1));
 | 
			
		||||
    }
 | 
			
		||||
    gil_scoped_release(const gil_scoped_release &) = delete;
 | 
			
		||||
    gil_scoped_release &operator=(const gil_scoped_release &) = delete;
 | 
			
		||||
    void disarm() {}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // WITH_THREAD
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
 | 
			
		||||
							
								
								
									
										265
									
								
								3rdparty/pybind11/include/pybind11/iostream.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										265
									
								
								3rdparty/pybind11/include/pybind11/iostream.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,265 @@
 | 
			
		||||
/*
 | 
			
		||||
    pybind11/iostream.h -- Tools to assist with redirecting cout and cerr to Python
 | 
			
		||||
 | 
			
		||||
    Copyright (c) 2017 Henry F. Schreiner
 | 
			
		||||
 | 
			
		||||
    All rights reserved. Use of this source code is governed by a
 | 
			
		||||
    BSD-style license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
    WARNING: The implementation in this file is NOT thread safe. Multiple
 | 
			
		||||
    threads writing to a redirected ostream concurrently cause data races
 | 
			
		||||
    and potentially buffer overflows. Therefore it is currently a requirement
 | 
			
		||||
    that all (possibly) concurrent redirected ostream writes are protected by
 | 
			
		||||
    a mutex.
 | 
			
		||||
    #HelpAppreciated: Work on iostream.h thread safety.
 | 
			
		||||
    For more background see the discussions under
 | 
			
		||||
    https://github.com/pybind/pybind11/pull/2982 and
 | 
			
		||||
    https://github.com/pybind/pybind11/pull/2995.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "pybind11.h"
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <iterator>
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <ostream>
 | 
			
		||||
#include <streambuf>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <utility>
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(detail)
 | 
			
		||||
 | 
			
		||||
// Buffer that writes to Python instead of C++
 | 
			
		||||
class pythonbuf : public std::streambuf {
 | 
			
		||||
private:
 | 
			
		||||
    using traits_type = std::streambuf::traits_type;
 | 
			
		||||
 | 
			
		||||
    const size_t buf_size;
 | 
			
		||||
    std::unique_ptr<char[]> d_buffer;
 | 
			
		||||
    object pywrite;
 | 
			
		||||
    object pyflush;
 | 
			
		||||
 | 
			
		||||
    int overflow(int c) override {
 | 
			
		||||
        if (!traits_type::eq_int_type(c, traits_type::eof())) {
 | 
			
		||||
            *pptr() = traits_type::to_char_type(c);
 | 
			
		||||
            pbump(1);
 | 
			
		||||
        }
 | 
			
		||||
        return sync() == 0 ? traits_type::not_eof(c) : traits_type::eof();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Computes how many bytes at the end of the buffer are part of an
 | 
			
		||||
    // incomplete sequence of UTF-8 bytes.
 | 
			
		||||
    // Precondition: pbase() < pptr()
 | 
			
		||||
    size_t utf8_remainder() const {
 | 
			
		||||
        const auto rbase = std::reverse_iterator<char *>(pbase());
 | 
			
		||||
        const auto rpptr = std::reverse_iterator<char *>(pptr());
 | 
			
		||||
        auto is_ascii = [](char c) { return (static_cast<unsigned char>(c) & 0x80) == 0x00; };
 | 
			
		||||
        auto is_leading = [](char c) { return (static_cast<unsigned char>(c) & 0xC0) == 0xC0; };
 | 
			
		||||
        auto is_leading_2b = [](char c) { return static_cast<unsigned char>(c) <= 0xDF; };
 | 
			
		||||
        auto is_leading_3b = [](char c) { return static_cast<unsigned char>(c) <= 0xEF; };
 | 
			
		||||
        // If the last character is ASCII, there are no incomplete code points
 | 
			
		||||
        if (is_ascii(*rpptr)) {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
        // Otherwise, work back from the end of the buffer and find the first
 | 
			
		||||
        // UTF-8 leading byte
 | 
			
		||||
        const auto rpend = rbase - rpptr >= 3 ? rpptr + 3 : rbase;
 | 
			
		||||
        const auto leading = std::find_if(rpptr, rpend, is_leading);
 | 
			
		||||
        if (leading == rbase) {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
        const auto dist = static_cast<size_t>(leading - rpptr);
 | 
			
		||||
        size_t remainder = 0;
 | 
			
		||||
 | 
			
		||||
        if (dist == 0) {
 | 
			
		||||
            remainder = 1; // 1-byte code point is impossible
 | 
			
		||||
        } else if (dist == 1) {
 | 
			
		||||
            remainder = is_leading_2b(*leading) ? 0 : dist + 1;
 | 
			
		||||
        } else if (dist == 2) {
 | 
			
		||||
            remainder = is_leading_3b(*leading) ? 0 : dist + 1;
 | 
			
		||||
        }
 | 
			
		||||
        // else if (dist >= 3), at least 4 bytes before encountering an UTF-8
 | 
			
		||||
        // leading byte, either no remainder or invalid UTF-8.
 | 
			
		||||
        // Invalid UTF-8 will cause an exception later when converting
 | 
			
		||||
        // to a Python string, so that's not handled here.
 | 
			
		||||
        return remainder;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // This function must be non-virtual to be called in a destructor.
 | 
			
		||||
    int _sync() {
 | 
			
		||||
        if (pbase() != pptr()) { // If buffer is not empty
 | 
			
		||||
            gil_scoped_acquire tmp;
 | 
			
		||||
            // This subtraction cannot be negative, so dropping the sign.
 | 
			
		||||
            auto size = static_cast<size_t>(pptr() - pbase());
 | 
			
		||||
            size_t remainder = utf8_remainder();
 | 
			
		||||
 | 
			
		||||
            if (size > remainder) {
 | 
			
		||||
                str line(pbase(), size - remainder);
 | 
			
		||||
                pywrite(std::move(line));
 | 
			
		||||
                pyflush();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Copy the remainder at the end of the buffer to the beginning:
 | 
			
		||||
            if (remainder > 0) {
 | 
			
		||||
                std::memmove(pbase(), pptr() - remainder, remainder);
 | 
			
		||||
            }
 | 
			
		||||
            setp(pbase(), epptr());
 | 
			
		||||
            pbump(static_cast<int>(remainder));
 | 
			
		||||
        }
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int sync() override { return _sync(); }
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    explicit pythonbuf(const object &pyostream, size_t buffer_size = 1024)
 | 
			
		||||
        : buf_size(buffer_size), d_buffer(new char[buf_size]), pywrite(pyostream.attr("write")),
 | 
			
		||||
          pyflush(pyostream.attr("flush")) {
 | 
			
		||||
        setp(d_buffer.get(), d_buffer.get() + buf_size - 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pythonbuf(pythonbuf &&) = default;
 | 
			
		||||
 | 
			
		||||
    /// Sync before destroy
 | 
			
		||||
    ~pythonbuf() override { _sync(); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_END(detail)
 | 
			
		||||
 | 
			
		||||
/** \rst
 | 
			
		||||
    This a move-only guard that redirects output.
 | 
			
		||||
 | 
			
		||||
    .. code-block:: cpp
 | 
			
		||||
 | 
			
		||||
        #include <pybind11/iostream.h>
 | 
			
		||||
 | 
			
		||||
        ...
 | 
			
		||||
 | 
			
		||||
        {
 | 
			
		||||
            py::scoped_ostream_redirect output;
 | 
			
		||||
            std::cout << "Hello, World!"; // Python stdout
 | 
			
		||||
        } // <-- return std::cout to normal
 | 
			
		||||
 | 
			
		||||
    You can explicitly pass the c++ stream and the python object,
 | 
			
		||||
    for example to guard stderr instead.
 | 
			
		||||
 | 
			
		||||
    .. code-block:: cpp
 | 
			
		||||
 | 
			
		||||
        {
 | 
			
		||||
            py::scoped_ostream_redirect output{
 | 
			
		||||
                std::cerr, py::module::import("sys").attr("stderr")};
 | 
			
		||||
            std::cout << "Hello, World!";
 | 
			
		||||
        }
 | 
			
		||||
 \endrst */
 | 
			
		||||
class scoped_ostream_redirect {
 | 
			
		||||
protected:
 | 
			
		||||
    std::streambuf *old;
 | 
			
		||||
    std::ostream &costream;
 | 
			
		||||
    detail::pythonbuf buffer;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    explicit scoped_ostream_redirect(std::ostream &costream = std::cout,
 | 
			
		||||
                                     const object &pyostream
 | 
			
		||||
                                     = module_::import("sys").attr("stdout"))
 | 
			
		||||
        : costream(costream), buffer(pyostream) {
 | 
			
		||||
        old = costream.rdbuf(&buffer);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~scoped_ostream_redirect() { costream.rdbuf(old); }
 | 
			
		||||
 | 
			
		||||
    scoped_ostream_redirect(const scoped_ostream_redirect &) = delete;
 | 
			
		||||
    scoped_ostream_redirect(scoped_ostream_redirect &&other) = default;
 | 
			
		||||
    scoped_ostream_redirect &operator=(const scoped_ostream_redirect &) = delete;
 | 
			
		||||
    scoped_ostream_redirect &operator=(scoped_ostream_redirect &&) = delete;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** \rst
 | 
			
		||||
    Like `scoped_ostream_redirect`, but redirects cerr by default. This class
 | 
			
		||||
    is provided primary to make ``py::call_guard`` easier to make.
 | 
			
		||||
 | 
			
		||||
    .. code-block:: cpp
 | 
			
		||||
 | 
			
		||||
     m.def("noisy_func", &noisy_func,
 | 
			
		||||
           py::call_guard<scoped_ostream_redirect,
 | 
			
		||||
                          scoped_estream_redirect>());
 | 
			
		||||
 | 
			
		||||
\endrst */
 | 
			
		||||
class scoped_estream_redirect : public scoped_ostream_redirect {
 | 
			
		||||
public:
 | 
			
		||||
    explicit scoped_estream_redirect(std::ostream &costream = std::cerr,
 | 
			
		||||
                                     const object &pyostream
 | 
			
		||||
                                     = module_::import("sys").attr("stderr"))
 | 
			
		||||
        : scoped_ostream_redirect(costream, pyostream) {}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(detail)
 | 
			
		||||
 | 
			
		||||
// Class to redirect output as a context manager. C++ backend.
 | 
			
		||||
class OstreamRedirect {
 | 
			
		||||
    bool do_stdout_;
 | 
			
		||||
    bool do_stderr_;
 | 
			
		||||
    std::unique_ptr<scoped_ostream_redirect> redirect_stdout;
 | 
			
		||||
    std::unique_ptr<scoped_estream_redirect> redirect_stderr;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    explicit OstreamRedirect(bool do_stdout = true, bool do_stderr = true)
 | 
			
		||||
        : do_stdout_(do_stdout), do_stderr_(do_stderr) {}
 | 
			
		||||
 | 
			
		||||
    void enter() {
 | 
			
		||||
        if (do_stdout_) {
 | 
			
		||||
            redirect_stdout.reset(new scoped_ostream_redirect());
 | 
			
		||||
        }
 | 
			
		||||
        if (do_stderr_) {
 | 
			
		||||
            redirect_stderr.reset(new scoped_estream_redirect());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void exit() {
 | 
			
		||||
        redirect_stdout.reset();
 | 
			
		||||
        redirect_stderr.reset();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_END(detail)
 | 
			
		||||
 | 
			
		||||
/** \rst
 | 
			
		||||
    This is a helper function to add a C++ redirect context manager to Python
 | 
			
		||||
    instead of using a C++ guard. To use it, add the following to your binding code:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: cpp
 | 
			
		||||
 | 
			
		||||
        #include <pybind11/iostream.h>
 | 
			
		||||
 | 
			
		||||
        ...
 | 
			
		||||
 | 
			
		||||
        py::add_ostream_redirect(m, "ostream_redirect");
 | 
			
		||||
 | 
			
		||||
    You now have a Python context manager that redirects your output:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        with m.ostream_redirect():
 | 
			
		||||
            m.print_to_cout_function()
 | 
			
		||||
 | 
			
		||||
    This manager can optionally be told which streams to operate on:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        with m.ostream_redirect(stdout=true, stderr=true):
 | 
			
		||||
            m.noisy_function_with_error_printing()
 | 
			
		||||
 | 
			
		||||
 \endrst */
 | 
			
		||||
inline class_<detail::OstreamRedirect>
 | 
			
		||||
add_ostream_redirect(module_ m, const std::string &name = "ostream_redirect") {
 | 
			
		||||
    return class_<detail::OstreamRedirect>(std::move(m), name.c_str(), module_local())
 | 
			
		||||
        .def(init<bool, bool>(), arg("stdout") = true, arg("stderr") = true)
 | 
			
		||||
        .def("__enter__", &detail::OstreamRedirect::enter)
 | 
			
		||||
        .def("__exit__", [](detail::OstreamRedirect &self_, const args &) { self_.exit(); });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
 | 
			
		||||
							
								
								
									
										1998
									
								
								3rdparty/pybind11/include/pybind11/numpy.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1998
									
								
								3rdparty/pybind11/include/pybind11/numpy.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										202
									
								
								3rdparty/pybind11/include/pybind11/operators.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								3rdparty/pybind11/include/pybind11/operators.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,202 @@
 | 
			
		||||
/*
 | 
			
		||||
    pybind11/operator.h: Metatemplates for operator overloading
 | 
			
		||||
 | 
			
		||||
    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
 | 
			
		||||
 | 
			
		||||
    All rights reserved. Use of this source code is governed by a
 | 
			
		||||
    BSD-style license that can be found in the LICENSE file.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "pybind11.h"
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(detail)
 | 
			
		||||
 | 
			
		||||
/// Enumeration with all supported operator types
 | 
			
		||||
enum op_id : int {
 | 
			
		||||
    op_add,
 | 
			
		||||
    op_sub,
 | 
			
		||||
    op_mul,
 | 
			
		||||
    op_div,
 | 
			
		||||
    op_mod,
 | 
			
		||||
    op_divmod,
 | 
			
		||||
    op_pow,
 | 
			
		||||
    op_lshift,
 | 
			
		||||
    op_rshift,
 | 
			
		||||
    op_and,
 | 
			
		||||
    op_xor,
 | 
			
		||||
    op_or,
 | 
			
		||||
    op_neg,
 | 
			
		||||
    op_pos,
 | 
			
		||||
    op_abs,
 | 
			
		||||
    op_invert,
 | 
			
		||||
    op_int,
 | 
			
		||||
    op_long,
 | 
			
		||||
    op_float,
 | 
			
		||||
    op_str,
 | 
			
		||||
    op_cmp,
 | 
			
		||||
    op_gt,
 | 
			
		||||
    op_ge,
 | 
			
		||||
    op_lt,
 | 
			
		||||
    op_le,
 | 
			
		||||
    op_eq,
 | 
			
		||||
    op_ne,
 | 
			
		||||
    op_iadd,
 | 
			
		||||
    op_isub,
 | 
			
		||||
    op_imul,
 | 
			
		||||
    op_idiv,
 | 
			
		||||
    op_imod,
 | 
			
		||||
    op_ilshift,
 | 
			
		||||
    op_irshift,
 | 
			
		||||
    op_iand,
 | 
			
		||||
    op_ixor,
 | 
			
		||||
    op_ior,
 | 
			
		||||
    op_complex,
 | 
			
		||||
    op_bool,
 | 
			
		||||
    op_nonzero,
 | 
			
		||||
    op_repr,
 | 
			
		||||
    op_truediv,
 | 
			
		||||
    op_itruediv,
 | 
			
		||||
    op_hash
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum op_type : int {
 | 
			
		||||
    op_l, /* base type on left */
 | 
			
		||||
    op_r, /* base type on right */
 | 
			
		||||
    op_u  /* unary operator */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct self_t {};
 | 
			
		||||
static const self_t self = self_t();
 | 
			
		||||
 | 
			
		||||
/// Type for an unused type slot
 | 
			
		||||
struct undefined_t {};
 | 
			
		||||
 | 
			
		||||
/// Don't warn about an unused variable
 | 
			
		||||
inline self_t __self() { return self; }
 | 
			
		||||
 | 
			
		||||
/// base template of operator implementations
 | 
			
		||||
template <op_id, op_type, typename B, typename L, typename R>
 | 
			
		||||
struct op_impl {};
 | 
			
		||||
 | 
			
		||||
/// Operator implementation generator
 | 
			
		||||
template <op_id id, op_type ot, typename L, typename R>
 | 
			
		||||
struct op_ {
 | 
			
		||||
    static constexpr bool op_enable_if_hook = true;
 | 
			
		||||
    template <typename Class, typename... Extra>
 | 
			
		||||
    void execute(Class &cl, const Extra &...extra) const {
 | 
			
		||||
        using Base = typename Class::type;
 | 
			
		||||
        using L_type = conditional_t<std::is_same<L, self_t>::value, Base, L>;
 | 
			
		||||
        using R_type = conditional_t<std::is_same<R, self_t>::value, Base, R>;
 | 
			
		||||
        using op = op_impl<id, ot, Base, L_type, R_type>;
 | 
			
		||||
        cl.def(op::name(), &op::execute, is_operator(), extra...);
 | 
			
		||||
    }
 | 
			
		||||
    template <typename Class, typename... Extra>
 | 
			
		||||
    void execute_cast(Class &cl, const Extra &...extra) const {
 | 
			
		||||
        using Base = typename Class::type;
 | 
			
		||||
        using L_type = conditional_t<std::is_same<L, self_t>::value, Base, L>;
 | 
			
		||||
        using R_type = conditional_t<std::is_same<R, self_t>::value, Base, R>;
 | 
			
		||||
        using op = op_impl<id, ot, Base, L_type, R_type>;
 | 
			
		||||
        cl.def(op::name(), &op::execute_cast, is_operator(), extra...);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define PYBIND11_BINARY_OPERATOR(id, rid, op, expr)                                               \
 | 
			
		||||
    template <typename B, typename L, typename R>                                                 \
 | 
			
		||||
    struct op_impl<op_##id, op_l, B, L, R> {                                                      \
 | 
			
		||||
        static char const *name() { return "__" #id "__"; }                                       \
 | 
			
		||||
        static auto execute(const L &l, const R &r) -> decltype(expr) { return (expr); }          \
 | 
			
		||||
        static B execute_cast(const L &l, const R &r) { return B(expr); }                         \
 | 
			
		||||
    };                                                                                            \
 | 
			
		||||
    template <typename B, typename L, typename R>                                                 \
 | 
			
		||||
    struct op_impl<op_##id, op_r, B, L, R> {                                                      \
 | 
			
		||||
        static char const *name() { return "__" #rid "__"; }                                      \
 | 
			
		||||
        static auto execute(const R &r, const L &l) -> decltype(expr) { return (expr); }          \
 | 
			
		||||
        static B execute_cast(const R &r, const L &l) { return B(expr); }                         \
 | 
			
		||||
    };                                                                                            \
 | 
			
		||||
    inline op_<op_##id, op_l, self_t, self_t> op(const self_t &, const self_t &) {                \
 | 
			
		||||
        return op_<op_##id, op_l, self_t, self_t>();                                              \
 | 
			
		||||
    }                                                                                             \
 | 
			
		||||
    template <typename T>                                                                         \
 | 
			
		||||
    op_<op_##id, op_l, self_t, T> op(const self_t &, const T &) {                                 \
 | 
			
		||||
        return op_<op_##id, op_l, self_t, T>();                                                   \
 | 
			
		||||
    }                                                                                             \
 | 
			
		||||
    template <typename T>                                                                         \
 | 
			
		||||
    op_<op_##id, op_r, T, self_t> op(const T &, const self_t &) {                                 \
 | 
			
		||||
        return op_<op_##id, op_r, T, self_t>();                                                   \
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#define PYBIND11_INPLACE_OPERATOR(id, op, expr)                                                   \
 | 
			
		||||
    template <typename B, typename L, typename R>                                                 \
 | 
			
		||||
    struct op_impl<op_##id, op_l, B, L, R> {                                                      \
 | 
			
		||||
        static char const *name() { return "__" #id "__"; }                                       \
 | 
			
		||||
        static auto execute(L &l, const R &r) -> decltype(expr) { return expr; }                  \
 | 
			
		||||
        static B execute_cast(L &l, const R &r) { return B(expr); }                               \
 | 
			
		||||
    };                                                                                            \
 | 
			
		||||
    template <typename T>                                                                         \
 | 
			
		||||
    op_<op_##id, op_l, self_t, T> op(const self_t &, const T &) {                                 \
 | 
			
		||||
        return op_<op_##id, op_l, self_t, T>();                                                   \
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#define PYBIND11_UNARY_OPERATOR(id, op, expr)                                                     \
 | 
			
		||||
    template <typename B, typename L>                                                             \
 | 
			
		||||
    struct op_impl<op_##id, op_u, B, L, undefined_t> {                                            \
 | 
			
		||||
        static char const *name() { return "__" #id "__"; }                                       \
 | 
			
		||||
        static auto execute(const L &l) -> decltype(expr) { return expr; }                        \
 | 
			
		||||
        static B execute_cast(const L &l) { return B(expr); }                                     \
 | 
			
		||||
    };                                                                                            \
 | 
			
		||||
    inline op_<op_##id, op_u, self_t, undefined_t> op(const self_t &) {                           \
 | 
			
		||||
        return op_<op_##id, op_u, self_t, undefined_t>();                                         \
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
PYBIND11_BINARY_OPERATOR(sub, rsub, operator-, l - r)
 | 
			
		||||
PYBIND11_BINARY_OPERATOR(add, radd, operator+, l + r)
 | 
			
		||||
PYBIND11_BINARY_OPERATOR(mul, rmul, operator*, l *r)
 | 
			
		||||
PYBIND11_BINARY_OPERATOR(truediv, rtruediv, operator/, l / r)
 | 
			
		||||
PYBIND11_BINARY_OPERATOR(mod, rmod, operator%, l % r)
 | 
			
		||||
PYBIND11_BINARY_OPERATOR(lshift, rlshift, operator<<, l << r)
 | 
			
		||||
PYBIND11_BINARY_OPERATOR(rshift, rrshift, operator>>, l >> r)
 | 
			
		||||
PYBIND11_BINARY_OPERATOR(and, rand, operator&, l &r)
 | 
			
		||||
PYBIND11_BINARY_OPERATOR(xor, rxor, operator^, l ^ r)
 | 
			
		||||
PYBIND11_BINARY_OPERATOR(eq, eq, operator==, l == r)
 | 
			
		||||
PYBIND11_BINARY_OPERATOR(ne, ne, operator!=, l != r)
 | 
			
		||||
PYBIND11_BINARY_OPERATOR(or, ror, operator|, l | r)
 | 
			
		||||
PYBIND11_BINARY_OPERATOR(gt, lt, operator>, l > r)
 | 
			
		||||
PYBIND11_BINARY_OPERATOR(ge, le, operator>=, l >= r)
 | 
			
		||||
PYBIND11_BINARY_OPERATOR(lt, gt, operator<, l < r)
 | 
			
		||||
PYBIND11_BINARY_OPERATOR(le, ge, operator<=, l <= r)
 | 
			
		||||
// PYBIND11_BINARY_OPERATOR(pow,       rpow,         pow,          std::pow(l,  r))
 | 
			
		||||
PYBIND11_INPLACE_OPERATOR(iadd, operator+=, l += r)
 | 
			
		||||
PYBIND11_INPLACE_OPERATOR(isub, operator-=, l -= r)
 | 
			
		||||
PYBIND11_INPLACE_OPERATOR(imul, operator*=, l *= r)
 | 
			
		||||
PYBIND11_INPLACE_OPERATOR(itruediv, operator/=, l /= r)
 | 
			
		||||
PYBIND11_INPLACE_OPERATOR(imod, operator%=, l %= r)
 | 
			
		||||
PYBIND11_INPLACE_OPERATOR(ilshift, operator<<=, l <<= r)
 | 
			
		||||
PYBIND11_INPLACE_OPERATOR(irshift, operator>>=, l >>= r)
 | 
			
		||||
PYBIND11_INPLACE_OPERATOR(iand, operator&=, l &= r)
 | 
			
		||||
PYBIND11_INPLACE_OPERATOR(ixor, operator^=, l ^= r)
 | 
			
		||||
PYBIND11_INPLACE_OPERATOR(ior, operator|=, l |= r)
 | 
			
		||||
PYBIND11_UNARY_OPERATOR(neg, operator-, -l)
 | 
			
		||||
PYBIND11_UNARY_OPERATOR(pos, operator+, +l)
 | 
			
		||||
// WARNING: This usage of `abs` should only be done for existing STL overloads.
 | 
			
		||||
// Adding overloads directly in to the `std::` namespace is advised against:
 | 
			
		||||
// https://en.cppreference.com/w/cpp/language/extending_std
 | 
			
		||||
PYBIND11_UNARY_OPERATOR(abs, abs, std::abs(l))
 | 
			
		||||
PYBIND11_UNARY_OPERATOR(hash, hash, std::hash<L>()(l))
 | 
			
		||||
PYBIND11_UNARY_OPERATOR(invert, operator~, (~l))
 | 
			
		||||
PYBIND11_UNARY_OPERATOR(bool, operator!, !!l)
 | 
			
		||||
PYBIND11_UNARY_OPERATOR(int, int_, (int) l)
 | 
			
		||||
PYBIND11_UNARY_OPERATOR(float, float_, (double) l)
 | 
			
		||||
 | 
			
		||||
#undef PYBIND11_BINARY_OPERATOR
 | 
			
		||||
#undef PYBIND11_INPLACE_OPERATOR
 | 
			
		||||
#undef PYBIND11_UNARY_OPERATOR
 | 
			
		||||
PYBIND11_NAMESPACE_END(detail)
 | 
			
		||||
 | 
			
		||||
using detail::self;
 | 
			
		||||
// Add named operators so that they are accessible via `py::`.
 | 
			
		||||
using detail::hash;
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
 | 
			
		||||
							
								
								
									
										92
									
								
								3rdparty/pybind11/include/pybind11/options.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								3rdparty/pybind11/include/pybind11/options.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,92 @@
 | 
			
		||||
/*
 | 
			
		||||
    pybind11/options.h: global settings that are configurable at runtime.
 | 
			
		||||
 | 
			
		||||
    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
 | 
			
		||||
 | 
			
		||||
    All rights reserved. Use of this source code is governed by a
 | 
			
		||||
    BSD-style license that can be found in the LICENSE file.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "detail/common.h"
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
 | 
			
		||||
 | 
			
		||||
class options {
 | 
			
		||||
public:
 | 
			
		||||
    // Default RAII constructor, which leaves settings as they currently are.
 | 
			
		||||
    options() : previous_state(global_state()) {}
 | 
			
		||||
 | 
			
		||||
    // Class is non-copyable.
 | 
			
		||||
    options(const options &) = delete;
 | 
			
		||||
    options &operator=(const options &) = delete;
 | 
			
		||||
 | 
			
		||||
    // Destructor, which restores settings that were in effect before.
 | 
			
		||||
    ~options() { global_state() = previous_state; }
 | 
			
		||||
 | 
			
		||||
    // Setter methods (affect the global state):
 | 
			
		||||
 | 
			
		||||
    options &disable_user_defined_docstrings() & {
 | 
			
		||||
        global_state().show_user_defined_docstrings = false;
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    options &enable_user_defined_docstrings() & {
 | 
			
		||||
        global_state().show_user_defined_docstrings = true;
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    options &disable_function_signatures() & {
 | 
			
		||||
        global_state().show_function_signatures = false;
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    options &enable_function_signatures() & {
 | 
			
		||||
        global_state().show_function_signatures = true;
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    options &disable_enum_members_docstring() & {
 | 
			
		||||
        global_state().show_enum_members_docstring = false;
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    options &enable_enum_members_docstring() & {
 | 
			
		||||
        global_state().show_enum_members_docstring = true;
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Getter methods (return the global state):
 | 
			
		||||
 | 
			
		||||
    static bool show_user_defined_docstrings() {
 | 
			
		||||
        return global_state().show_user_defined_docstrings;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static bool show_function_signatures() { return global_state().show_function_signatures; }
 | 
			
		||||
 | 
			
		||||
    static bool show_enum_members_docstring() {
 | 
			
		||||
        return global_state().show_enum_members_docstring;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // This type is not meant to be allocated on the heap.
 | 
			
		||||
    void *operator new(size_t) = delete;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    struct state {
 | 
			
		||||
        bool show_user_defined_docstrings = true; //< Include user-supplied texts in docstrings.
 | 
			
		||||
        bool show_function_signatures = true;     //< Include auto-generated function signatures
 | 
			
		||||
                                                  //  in docstrings.
 | 
			
		||||
        bool show_enum_members_docstring = true;  //< Include auto-generated member list in enum
 | 
			
		||||
                                                  //  docstrings.
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    static state &global_state() {
 | 
			
		||||
        static state instance;
 | 
			
		||||
        return instance;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    state previous_state;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
 | 
			
		||||
							
								
								
									
										2890
									
								
								3rdparty/pybind11/include/pybind11/pybind11.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2890
									
								
								3rdparty/pybind11/include/pybind11/pybind11.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										2557
									
								
								3rdparty/pybind11/include/pybind11/pytypes.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2557
									
								
								3rdparty/pybind11/include/pybind11/pytypes.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										447
									
								
								3rdparty/pybind11/include/pybind11/stl.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										447
									
								
								3rdparty/pybind11/include/pybind11/stl.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,447 @@
 | 
			
		||||
/*
 | 
			
		||||
    pybind11/stl.h: Transparent conversion for STL data types
 | 
			
		||||
 | 
			
		||||
    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
 | 
			
		||||
 | 
			
		||||
    All rights reserved. Use of this source code is governed by a
 | 
			
		||||
    BSD-style license that can be found in the LICENSE file.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "pybind11.h"
 | 
			
		||||
#include "detail/common.h"
 | 
			
		||||
 | 
			
		||||
#include <deque>
 | 
			
		||||
#include <list>
 | 
			
		||||
#include <map>
 | 
			
		||||
#include <ostream>
 | 
			
		||||
#include <set>
 | 
			
		||||
#include <unordered_map>
 | 
			
		||||
#include <unordered_set>
 | 
			
		||||
#include <valarray>
 | 
			
		||||
 | 
			
		||||
// See `detail/common.h` for implementation of these guards.
 | 
			
		||||
#if defined(PYBIND11_HAS_OPTIONAL)
 | 
			
		||||
#    include <optional>
 | 
			
		||||
#elif defined(PYBIND11_HAS_EXP_OPTIONAL)
 | 
			
		||||
#    include <experimental/optional>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(PYBIND11_HAS_VARIANT)
 | 
			
		||||
#    include <variant>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(detail)
 | 
			
		||||
 | 
			
		||||
/// Extracts an const lvalue reference or rvalue reference for U based on the type of T (e.g. for
 | 
			
		||||
/// forwarding a container element).  Typically used indirect via forwarded_type(), below.
 | 
			
		||||
template <typename T, typename U>
 | 
			
		||||
using forwarded_type = conditional_t<std::is_lvalue_reference<T>::value,
 | 
			
		||||
                                     remove_reference_t<U> &,
 | 
			
		||||
                                     remove_reference_t<U> &&>;
 | 
			
		||||
 | 
			
		||||
/// Forwards a value U as rvalue or lvalue according to whether T is rvalue or lvalue; typically
 | 
			
		||||
/// used for forwarding a container's elements.
 | 
			
		||||
template <typename T, typename U>
 | 
			
		||||
constexpr forwarded_type<T, U> forward_like(U &&u) {
 | 
			
		||||
    return std::forward<detail::forwarded_type<T, U>>(std::forward<U>(u));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Checks if a container has a STL style reserve method.
 | 
			
		||||
// This will only return true for a `reserve()` with a `void` return.
 | 
			
		||||
template <typename C>
 | 
			
		||||
using has_reserve_method = std::is_same<decltype(std::declval<C>().reserve(0)), void>;
 | 
			
		||||
 | 
			
		||||
template <typename Type, typename Key>
 | 
			
		||||
struct set_caster {
 | 
			
		||||
    using type = Type;
 | 
			
		||||
    using key_conv = make_caster<Key>;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    template <typename T = Type, enable_if_t<has_reserve_method<T>::value, int> = 0>
 | 
			
		||||
    void reserve_maybe(const anyset &s, Type *) {
 | 
			
		||||
        value.reserve(s.size());
 | 
			
		||||
    }
 | 
			
		||||
    void reserve_maybe(const anyset &, void *) {}
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    bool load(handle src, bool convert) {
 | 
			
		||||
        if (!isinstance<anyset>(src)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        auto s = reinterpret_borrow<anyset>(src);
 | 
			
		||||
        value.clear();
 | 
			
		||||
        reserve_maybe(s, &value);
 | 
			
		||||
        for (auto entry : s) {
 | 
			
		||||
            key_conv conv;
 | 
			
		||||
            if (!conv.load(entry, convert)) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            value.insert(cast_op<Key &&>(std::move(conv)));
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    static handle cast(T &&src, return_value_policy policy, handle parent) {
 | 
			
		||||
        if (!std::is_lvalue_reference<T>::value) {
 | 
			
		||||
            policy = return_value_policy_override<Key>::policy(policy);
 | 
			
		||||
        }
 | 
			
		||||
        pybind11::set s;
 | 
			
		||||
        for (auto &&value : src) {
 | 
			
		||||
            auto value_ = reinterpret_steal<object>(
 | 
			
		||||
                key_conv::cast(detail::forward_like<T>(value), policy, parent));
 | 
			
		||||
            if (!value_ || !s.add(std::move(value_))) {
 | 
			
		||||
                return handle();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return s.release();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    PYBIND11_TYPE_CASTER(type, const_name("Set[") + key_conv::name + const_name("]"));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename Type, typename Key, typename Value>
 | 
			
		||||
struct map_caster {
 | 
			
		||||
    using key_conv = make_caster<Key>;
 | 
			
		||||
    using value_conv = make_caster<Value>;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    template <typename T = Type, enable_if_t<has_reserve_method<T>::value, int> = 0>
 | 
			
		||||
    void reserve_maybe(const dict &d, Type *) {
 | 
			
		||||
        value.reserve(d.size());
 | 
			
		||||
    }
 | 
			
		||||
    void reserve_maybe(const dict &, void *) {}
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    bool load(handle src, bool convert) {
 | 
			
		||||
        if (!isinstance<dict>(src)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        auto d = reinterpret_borrow<dict>(src);
 | 
			
		||||
        value.clear();
 | 
			
		||||
        reserve_maybe(d, &value);
 | 
			
		||||
        for (auto it : d) {
 | 
			
		||||
            key_conv kconv;
 | 
			
		||||
            value_conv vconv;
 | 
			
		||||
            if (!kconv.load(it.first.ptr(), convert) || !vconv.load(it.second.ptr(), convert)) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            value.emplace(cast_op<Key &&>(std::move(kconv)), cast_op<Value &&>(std::move(vconv)));
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    static handle cast(T &&src, return_value_policy policy, handle parent) {
 | 
			
		||||
        dict d;
 | 
			
		||||
        return_value_policy policy_key = policy;
 | 
			
		||||
        return_value_policy policy_value = policy;
 | 
			
		||||
        if (!std::is_lvalue_reference<T>::value) {
 | 
			
		||||
            policy_key = return_value_policy_override<Key>::policy(policy_key);
 | 
			
		||||
            policy_value = return_value_policy_override<Value>::policy(policy_value);
 | 
			
		||||
        }
 | 
			
		||||
        for (auto &&kv : src) {
 | 
			
		||||
            auto key = reinterpret_steal<object>(
 | 
			
		||||
                key_conv::cast(detail::forward_like<T>(kv.first), policy_key, parent));
 | 
			
		||||
            auto value = reinterpret_steal<object>(
 | 
			
		||||
                value_conv::cast(detail::forward_like<T>(kv.second), policy_value, parent));
 | 
			
		||||
            if (!key || !value) {
 | 
			
		||||
                return handle();
 | 
			
		||||
            }
 | 
			
		||||
            d[std::move(key)] = std::move(value);
 | 
			
		||||
        }
 | 
			
		||||
        return d.release();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    PYBIND11_TYPE_CASTER(Type,
 | 
			
		||||
                         const_name("Dict[") + key_conv::name + const_name(", ") + value_conv::name
 | 
			
		||||
                             + const_name("]"));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename Type, typename Value>
 | 
			
		||||
struct list_caster {
 | 
			
		||||
    using value_conv = make_caster<Value>;
 | 
			
		||||
 | 
			
		||||
    bool load(handle src, bool convert) {
 | 
			
		||||
        if (!isinstance<sequence>(src) || isinstance<bytes>(src) || isinstance<str>(src)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        auto s = reinterpret_borrow<sequence>(src);
 | 
			
		||||
        value.clear();
 | 
			
		||||
        reserve_maybe(s, &value);
 | 
			
		||||
        for (auto it : s) {
 | 
			
		||||
            value_conv conv;
 | 
			
		||||
            if (!conv.load(it, convert)) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            value.push_back(cast_op<Value &&>(std::move(conv)));
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    template <typename T = Type, enable_if_t<has_reserve_method<T>::value, int> = 0>
 | 
			
		||||
    void reserve_maybe(const sequence &s, Type *) {
 | 
			
		||||
        value.reserve(s.size());
 | 
			
		||||
    }
 | 
			
		||||
    void reserve_maybe(const sequence &, void *) {}
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    static handle cast(T &&src, return_value_policy policy, handle parent) {
 | 
			
		||||
        if (!std::is_lvalue_reference<T>::value) {
 | 
			
		||||
            policy = return_value_policy_override<Value>::policy(policy);
 | 
			
		||||
        }
 | 
			
		||||
        list l(src.size());
 | 
			
		||||
        ssize_t index = 0;
 | 
			
		||||
        for (auto &&value : src) {
 | 
			
		||||
            auto value_ = reinterpret_steal<object>(
 | 
			
		||||
                value_conv::cast(detail::forward_like<T>(value), policy, parent));
 | 
			
		||||
            if (!value_) {
 | 
			
		||||
                return handle();
 | 
			
		||||
            }
 | 
			
		||||
            PyList_SET_ITEM(l.ptr(), index++, value_.release().ptr()); // steals a reference
 | 
			
		||||
        }
 | 
			
		||||
        return l.release();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    PYBIND11_TYPE_CASTER(Type, const_name("List[") + value_conv::name + const_name("]"));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename Type, typename Alloc>
 | 
			
		||||
struct type_caster<std::vector<Type, Alloc>> : list_caster<std::vector<Type, Alloc>, Type> {};
 | 
			
		||||
 | 
			
		||||
template <typename Type, typename Alloc>
 | 
			
		||||
struct type_caster<std::deque<Type, Alloc>> : list_caster<std::deque<Type, Alloc>, Type> {};
 | 
			
		||||
 | 
			
		||||
template <typename Type, typename Alloc>
 | 
			
		||||
struct type_caster<std::list<Type, Alloc>> : list_caster<std::list<Type, Alloc>, Type> {};
 | 
			
		||||
 | 
			
		||||
template <typename ArrayType, typename Value, bool Resizable, size_t Size = 0>
 | 
			
		||||
struct array_caster {
 | 
			
		||||
    using value_conv = make_caster<Value>;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    template <bool R = Resizable>
 | 
			
		||||
    bool require_size(enable_if_t<R, size_t> size) {
 | 
			
		||||
        if (value.size() != size) {
 | 
			
		||||
            value.resize(size);
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    template <bool R = Resizable>
 | 
			
		||||
    bool require_size(enable_if_t<!R, size_t> size) {
 | 
			
		||||
        return size == Size;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    bool load(handle src, bool convert) {
 | 
			
		||||
        if (!isinstance<sequence>(src)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        auto l = reinterpret_borrow<sequence>(src);
 | 
			
		||||
        if (!require_size(l.size())) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        size_t ctr = 0;
 | 
			
		||||
        for (auto it : l) {
 | 
			
		||||
            value_conv conv;
 | 
			
		||||
            if (!conv.load(it, convert)) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            value[ctr++] = cast_op<Value &&>(std::move(conv));
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    static handle cast(T &&src, return_value_policy policy, handle parent) {
 | 
			
		||||
        list l(src.size());
 | 
			
		||||
        ssize_t index = 0;
 | 
			
		||||
        for (auto &&value : src) {
 | 
			
		||||
            auto value_ = reinterpret_steal<object>(
 | 
			
		||||
                value_conv::cast(detail::forward_like<T>(value), policy, parent));
 | 
			
		||||
            if (!value_) {
 | 
			
		||||
                return handle();
 | 
			
		||||
            }
 | 
			
		||||
            PyList_SET_ITEM(l.ptr(), index++, value_.release().ptr()); // steals a reference
 | 
			
		||||
        }
 | 
			
		||||
        return l.release();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    PYBIND11_TYPE_CASTER(ArrayType,
 | 
			
		||||
                         const_name<Resizable>(const_name(""), const_name("Annotated["))
 | 
			
		||||
                             + const_name("List[") + value_conv::name + const_name("]")
 | 
			
		||||
                             + const_name<Resizable>(const_name(""),
 | 
			
		||||
                                                     const_name(", FixedSize(")
 | 
			
		||||
                                                         + const_name<Size>() + const_name(")]")));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename Type, size_t Size>
 | 
			
		||||
struct type_caster<std::array<Type, Size>>
 | 
			
		||||
    : array_caster<std::array<Type, Size>, Type, false, Size> {};
 | 
			
		||||
 | 
			
		||||
template <typename Type>
 | 
			
		||||
struct type_caster<std::valarray<Type>> : array_caster<std::valarray<Type>, Type, true> {};
 | 
			
		||||
 | 
			
		||||
template <typename Key, typename Compare, typename Alloc>
 | 
			
		||||
struct type_caster<std::set<Key, Compare, Alloc>>
 | 
			
		||||
    : set_caster<std::set<Key, Compare, Alloc>, Key> {};
 | 
			
		||||
 | 
			
		||||
template <typename Key, typename Hash, typename Equal, typename Alloc>
 | 
			
		||||
struct type_caster<std::unordered_set<Key, Hash, Equal, Alloc>>
 | 
			
		||||
    : set_caster<std::unordered_set<Key, Hash, Equal, Alloc>, Key> {};
 | 
			
		||||
 | 
			
		||||
template <typename Key, typename Value, typename Compare, typename Alloc>
 | 
			
		||||
struct type_caster<std::map<Key, Value, Compare, Alloc>>
 | 
			
		||||
    : map_caster<std::map<Key, Value, Compare, Alloc>, Key, Value> {};
 | 
			
		||||
 | 
			
		||||
template <typename Key, typename Value, typename Hash, typename Equal, typename Alloc>
 | 
			
		||||
struct type_caster<std::unordered_map<Key, Value, Hash, Equal, Alloc>>
 | 
			
		||||
    : map_caster<std::unordered_map<Key, Value, Hash, Equal, Alloc>, Key, Value> {};
 | 
			
		||||
 | 
			
		||||
// This type caster is intended to be used for std::optional and std::experimental::optional
 | 
			
		||||
template <typename Type, typename Value = typename Type::value_type>
 | 
			
		||||
struct optional_caster {
 | 
			
		||||
    using value_conv = make_caster<Value>;
 | 
			
		||||
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    static handle cast(T &&src, return_value_policy policy, handle parent) {
 | 
			
		||||
        if (!src) {
 | 
			
		||||
            return none().release();
 | 
			
		||||
        }
 | 
			
		||||
        if (!std::is_lvalue_reference<T>::value) {
 | 
			
		||||
            policy = return_value_policy_override<Value>::policy(policy);
 | 
			
		||||
        }
 | 
			
		||||
        // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
 | 
			
		||||
        return value_conv::cast(*std::forward<T>(src), policy, parent);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool load(handle src, bool convert) {
 | 
			
		||||
        if (!src) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (src.is_none()) {
 | 
			
		||||
            return true; // default-constructed value is already empty
 | 
			
		||||
        }
 | 
			
		||||
        value_conv inner_caster;
 | 
			
		||||
        if (!inner_caster.load(src, convert)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        value.emplace(cast_op<Value &&>(std::move(inner_caster)));
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    PYBIND11_TYPE_CASTER(Type, const_name("Optional[") + value_conv::name + const_name("]"));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if defined(PYBIND11_HAS_OPTIONAL)
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct type_caster<std::optional<T>> : public optional_caster<std::optional<T>> {};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct type_caster<std::nullopt_t> : public void_caster<std::nullopt_t> {};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(PYBIND11_HAS_EXP_OPTIONAL)
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct type_caster<std::experimental::optional<T>>
 | 
			
		||||
    : public optional_caster<std::experimental::optional<T>> {};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct type_caster<std::experimental::nullopt_t>
 | 
			
		||||
    : public void_caster<std::experimental::nullopt_t> {};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/// Visit a variant and cast any found type to Python
 | 
			
		||||
struct variant_caster_visitor {
 | 
			
		||||
    return_value_policy policy;
 | 
			
		||||
    handle parent;
 | 
			
		||||
 | 
			
		||||
    using result_type = handle; // required by boost::variant in C++11
 | 
			
		||||
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    result_type operator()(T &&src) const {
 | 
			
		||||
        return make_caster<T>::cast(std::forward<T>(src), policy, parent);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Helper class which abstracts away variant's `visit` function. `std::variant` and similar
 | 
			
		||||
/// `namespace::variant` types which provide a `namespace::visit()` function are handled here
 | 
			
		||||
/// automatically using argument-dependent lookup. Users can provide specializations for other
 | 
			
		||||
/// variant-like classes, e.g. `boost::variant` and `boost::apply_visitor`.
 | 
			
		||||
template <template <typename...> class Variant>
 | 
			
		||||
struct visit_helper {
 | 
			
		||||
    template <typename... Args>
 | 
			
		||||
    static auto call(Args &&...args) -> decltype(visit(std::forward<Args>(args)...)) {
 | 
			
		||||
        return visit(std::forward<Args>(args)...);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Generic variant caster
 | 
			
		||||
template <typename Variant>
 | 
			
		||||
struct variant_caster;
 | 
			
		||||
 | 
			
		||||
template <template <typename...> class V, typename... Ts>
 | 
			
		||||
struct variant_caster<V<Ts...>> {
 | 
			
		||||
    static_assert(sizeof...(Ts) > 0, "Variant must consist of at least one alternative.");
 | 
			
		||||
 | 
			
		||||
    template <typename U, typename... Us>
 | 
			
		||||
    bool load_alternative(handle src, bool convert, type_list<U, Us...>) {
 | 
			
		||||
        auto caster = make_caster<U>();
 | 
			
		||||
        if (caster.load(src, convert)) {
 | 
			
		||||
            value = cast_op<U>(std::move(caster));
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        return load_alternative(src, convert, type_list<Us...>{});
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool load_alternative(handle, bool, type_list<>) { return false; }
 | 
			
		||||
 | 
			
		||||
    bool load(handle src, bool convert) {
 | 
			
		||||
        // Do a first pass without conversions to improve constructor resolution.
 | 
			
		||||
        // E.g. `py::int_(1).cast<variant<double, int>>()` needs to fill the `int`
 | 
			
		||||
        // slot of the variant. Without two-pass loading `double` would be filled
 | 
			
		||||
        // because it appears first and a conversion is possible.
 | 
			
		||||
        if (convert && load_alternative(src, false, type_list<Ts...>{})) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        return load_alternative(src, convert, type_list<Ts...>{});
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <typename Variant>
 | 
			
		||||
    static handle cast(Variant &&src, return_value_policy policy, handle parent) {
 | 
			
		||||
        return visit_helper<V>::call(variant_caster_visitor{policy, parent},
 | 
			
		||||
                                     std::forward<Variant>(src));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    using Type = V<Ts...>;
 | 
			
		||||
    PYBIND11_TYPE_CASTER(Type,
 | 
			
		||||
                         const_name("Union[") + detail::concat(make_caster<Ts>::name...)
 | 
			
		||||
                             + const_name("]"));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if defined(PYBIND11_HAS_VARIANT)
 | 
			
		||||
template <typename... Ts>
 | 
			
		||||
struct type_caster<std::variant<Ts...>> : variant_caster<std::variant<Ts...>> {};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct type_caster<std::monostate> : public void_caster<std::monostate> {};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_END(detail)
 | 
			
		||||
 | 
			
		||||
inline std::ostream &operator<<(std::ostream &os, const handle &obj) {
 | 
			
		||||
#ifdef PYBIND11_HAS_STRING_VIEW
 | 
			
		||||
    os << str(obj).cast<std::string_view>();
 | 
			
		||||
#else
 | 
			
		||||
    os << (std::string) str(obj);
 | 
			
		||||
#endif
 | 
			
		||||
    return os;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
 | 
			
		||||
							
								
								
									
										116
									
								
								3rdparty/pybind11/include/pybind11/stl/filesystem.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								3rdparty/pybind11/include/pybind11/stl/filesystem.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,116 @@
 | 
			
		||||
// Copyright (c) 2021 The Pybind Development Team.
 | 
			
		||||
// All rights reserved. Use of this source code is governed by a
 | 
			
		||||
// BSD-style license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "../pybind11.h"
 | 
			
		||||
#include "../detail/common.h"
 | 
			
		||||
#include "../detail/descr.h"
 | 
			
		||||
#include "../cast.h"
 | 
			
		||||
#include "../pytypes.h"
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#ifdef __has_include
 | 
			
		||||
#    if defined(PYBIND11_CPP17)
 | 
			
		||||
#        if __has_include(<filesystem>) && \
 | 
			
		||||
          PY_VERSION_HEX >= 0x03060000
 | 
			
		||||
#            include <filesystem>
 | 
			
		||||
#            define PYBIND11_HAS_FILESYSTEM 1
 | 
			
		||||
#        elif __has_include(<experimental/filesystem>)
 | 
			
		||||
#            include <experimental/filesystem>
 | 
			
		||||
#            define PYBIND11_HAS_EXPERIMENTAL_FILESYSTEM 1
 | 
			
		||||
#        endif
 | 
			
		||||
#    endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !defined(PYBIND11_HAS_FILESYSTEM) && !defined(PYBIND11_HAS_EXPERIMENTAL_FILESYSTEM)           \
 | 
			
		||||
    && !defined(PYBIND11_HAS_FILESYSTEM_IS_OPTIONAL)
 | 
			
		||||
#    error                                                                                        \
 | 
			
		||||
        "Neither #include <filesystem> nor #include <experimental/filesystem is available. (Use -DPYBIND11_HAS_FILESYSTEM_IS_OPTIONAL to ignore.)"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(detail)
 | 
			
		||||
 | 
			
		||||
#if defined(PYBIND11_HAS_FILESYSTEM) || defined(PYBIND11_HAS_EXPERIMENTAL_FILESYSTEM)
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct path_caster {
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    static PyObject *unicode_from_fs_native(const std::string &w) {
 | 
			
		||||
#    if !defined(PYPY_VERSION)
 | 
			
		||||
        return PyUnicode_DecodeFSDefaultAndSize(w.c_str(), ssize_t(w.size()));
 | 
			
		||||
#    else
 | 
			
		||||
        // PyPy mistakenly declares the first parameter as non-const.
 | 
			
		||||
        return PyUnicode_DecodeFSDefaultAndSize(const_cast<char *>(w.c_str()), ssize_t(w.size()));
 | 
			
		||||
#    endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static PyObject *unicode_from_fs_native(const std::wstring &w) {
 | 
			
		||||
        return PyUnicode_FromWideChar(w.c_str(), ssize_t(w.size()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    static handle cast(const T &path, return_value_policy, handle) {
 | 
			
		||||
        if (auto py_str = unicode_from_fs_native(path.native())) {
 | 
			
		||||
            return module_::import("pathlib")
 | 
			
		||||
                .attr("Path")(reinterpret_steal<object>(py_str))
 | 
			
		||||
                .release();
 | 
			
		||||
        }
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool load(handle handle, bool) {
 | 
			
		||||
        // PyUnicode_FSConverter and PyUnicode_FSDecoder normally take care of
 | 
			
		||||
        // calling PyOS_FSPath themselves, but that's broken on PyPy (PyPy
 | 
			
		||||
        // issue #3168) so we do it ourselves instead.
 | 
			
		||||
        PyObject *buf = PyOS_FSPath(handle.ptr());
 | 
			
		||||
        if (!buf) {
 | 
			
		||||
            PyErr_Clear();
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        PyObject *native = nullptr;
 | 
			
		||||
        if constexpr (std::is_same_v<typename T::value_type, char>) {
 | 
			
		||||
            if (PyUnicode_FSConverter(buf, &native) != 0) {
 | 
			
		||||
                if (auto *c_str = PyBytes_AsString(native)) {
 | 
			
		||||
                    // AsString returns a pointer to the internal buffer, which
 | 
			
		||||
                    // must not be free'd.
 | 
			
		||||
                    value = c_str;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } else if constexpr (std::is_same_v<typename T::value_type, wchar_t>) {
 | 
			
		||||
            if (PyUnicode_FSDecoder(buf, &native) != 0) {
 | 
			
		||||
                if (auto *c_str = PyUnicode_AsWideCharString(native, nullptr)) {
 | 
			
		||||
                    // AsWideCharString returns a new string that must be free'd.
 | 
			
		||||
                    value = c_str; // Copies the string.
 | 
			
		||||
                    PyMem_Free(c_str);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        Py_XDECREF(native);
 | 
			
		||||
        Py_DECREF(buf);
 | 
			
		||||
        if (PyErr_Occurred()) {
 | 
			
		||||
            PyErr_Clear();
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    PYBIND11_TYPE_CASTER(T, const_name("os.PathLike"));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // PYBIND11_HAS_FILESYSTEM || defined(PYBIND11_HAS_EXPERIMENTAL_FILESYSTEM)
 | 
			
		||||
 | 
			
		||||
#if defined(PYBIND11_HAS_FILESYSTEM)
 | 
			
		||||
template <>
 | 
			
		||||
struct type_caster<std::filesystem::path> : public path_caster<std::filesystem::path> {};
 | 
			
		||||
#elif defined(PYBIND11_HAS_EXPERIMENTAL_FILESYSTEM)
 | 
			
		||||
template <>
 | 
			
		||||
struct type_caster<std::experimental::filesystem::path>
 | 
			
		||||
    : public path_caster<std::experimental::filesystem::path> {};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_END(detail)
 | 
			
		||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
 | 
			
		||||
							
								
								
									
										851
									
								
								3rdparty/pybind11/include/pybind11/stl_bind.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										851
									
								
								3rdparty/pybind11/include/pybind11/stl_bind.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,851 @@
 | 
			
		||||
/*
 | 
			
		||||
    pybind11/std_bind.h: Binding generators for STL data types
 | 
			
		||||
 | 
			
		||||
    Copyright (c) 2016 Sergey Lyskov and Wenzel Jakob
 | 
			
		||||
 | 
			
		||||
    All rights reserved. Use of this source code is governed by a
 | 
			
		||||
    BSD-style license that can be found in the LICENSE file.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "detail/common.h"
 | 
			
		||||
#include "detail/type_caster_base.h"
 | 
			
		||||
#include "cast.h"
 | 
			
		||||
#include "operators.h"
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <sstream>
 | 
			
		||||
#include <type_traits>
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(detail)
 | 
			
		||||
 | 
			
		||||
/* SFINAE helper class used by 'is_comparable */
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct container_traits {
 | 
			
		||||
    template <typename T2>
 | 
			
		||||
    static std::true_type
 | 
			
		||||
    test_comparable(decltype(std::declval<const T2 &>() == std::declval<const T2 &>()) *);
 | 
			
		||||
    template <typename T2>
 | 
			
		||||
    static std::false_type test_comparable(...);
 | 
			
		||||
    template <typename T2>
 | 
			
		||||
    static std::true_type test_value(typename T2::value_type *);
 | 
			
		||||
    template <typename T2>
 | 
			
		||||
    static std::false_type test_value(...);
 | 
			
		||||
    template <typename T2>
 | 
			
		||||
    static std::true_type test_pair(typename T2::first_type *, typename T2::second_type *);
 | 
			
		||||
    template <typename T2>
 | 
			
		||||
    static std::false_type test_pair(...);
 | 
			
		||||
 | 
			
		||||
    static constexpr const bool is_comparable
 | 
			
		||||
        = std::is_same<std::true_type, decltype(test_comparable<T>(nullptr))>::value;
 | 
			
		||||
    static constexpr const bool is_pair
 | 
			
		||||
        = std::is_same<std::true_type, decltype(test_pair<T>(nullptr, nullptr))>::value;
 | 
			
		||||
    static constexpr const bool is_vector
 | 
			
		||||
        = std::is_same<std::true_type, decltype(test_value<T>(nullptr))>::value;
 | 
			
		||||
    static constexpr const bool is_element = !is_pair && !is_vector;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Default: is_comparable -> std::false_type */
 | 
			
		||||
template <typename T, typename SFINAE = void>
 | 
			
		||||
struct is_comparable : std::false_type {};
 | 
			
		||||
 | 
			
		||||
/* For non-map data structures, check whether operator== can be instantiated */
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct is_comparable<
 | 
			
		||||
    T,
 | 
			
		||||
    enable_if_t<container_traits<T>::is_element && container_traits<T>::is_comparable>>
 | 
			
		||||
    : std::true_type {};
 | 
			
		||||
 | 
			
		||||
/* For a vector/map data structure, recursively check the value type
 | 
			
		||||
   (which is std::pair for maps) */
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct is_comparable<T, enable_if_t<container_traits<T>::is_vector>>
 | 
			
		||||
    : is_comparable<typename recursive_container_traits<T>::type_to_check_recursively> {};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct is_comparable<recursive_bottom> : std::true_type {};
 | 
			
		||||
 | 
			
		||||
/* For pairs, recursively check the two data types */
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct is_comparable<T, enable_if_t<container_traits<T>::is_pair>> {
 | 
			
		||||
    static constexpr const bool value = is_comparable<typename T::first_type>::value
 | 
			
		||||
                                        && is_comparable<typename T::second_type>::value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Fallback functions */
 | 
			
		||||
template <typename, typename, typename... Args>
 | 
			
		||||
void vector_if_copy_constructible(const Args &...) {}
 | 
			
		||||
template <typename, typename, typename... Args>
 | 
			
		||||
void vector_if_equal_operator(const Args &...) {}
 | 
			
		||||
template <typename, typename, typename... Args>
 | 
			
		||||
void vector_if_insertion_operator(const Args &...) {}
 | 
			
		||||
template <typename, typename, typename... Args>
 | 
			
		||||
void vector_modifiers(const Args &...) {}
 | 
			
		||||
 | 
			
		||||
template <typename Vector, typename Class_>
 | 
			
		||||
void vector_if_copy_constructible(enable_if_t<is_copy_constructible<Vector>::value, Class_> &cl) {
 | 
			
		||||
    cl.def(init<const Vector &>(), "Copy constructor");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Vector, typename Class_>
 | 
			
		||||
void vector_if_equal_operator(enable_if_t<is_comparable<Vector>::value, Class_> &cl) {
 | 
			
		||||
    using T = typename Vector::value_type;
 | 
			
		||||
 | 
			
		||||
    cl.def(self == self);
 | 
			
		||||
    cl.def(self != self);
 | 
			
		||||
 | 
			
		||||
    cl.def(
 | 
			
		||||
        "count",
 | 
			
		||||
        [](const Vector &v, const T &x) { return std::count(v.begin(), v.end(), x); },
 | 
			
		||||
        arg("x"),
 | 
			
		||||
        "Return the number of times ``x`` appears in the list");
 | 
			
		||||
 | 
			
		||||
    cl.def(
 | 
			
		||||
        "remove",
 | 
			
		||||
        [](Vector &v, const T &x) {
 | 
			
		||||
            auto p = std::find(v.begin(), v.end(), x);
 | 
			
		||||
            if (p != v.end()) {
 | 
			
		||||
                v.erase(p);
 | 
			
		||||
            } else {
 | 
			
		||||
                throw value_error();
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        arg("x"),
 | 
			
		||||
        "Remove the first item from the list whose value is x. "
 | 
			
		||||
        "It is an error if there is no such item.");
 | 
			
		||||
 | 
			
		||||
    cl.def(
 | 
			
		||||
        "__contains__",
 | 
			
		||||
        [](const Vector &v, const T &x) { return std::find(v.begin(), v.end(), x) != v.end(); },
 | 
			
		||||
        arg("x"),
 | 
			
		||||
        "Return true the container contains ``x``");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Vector modifiers -- requires a copyable vector_type:
 | 
			
		||||
// (Technically, some of these (pop and __delitem__) don't actually require copyability, but it
 | 
			
		||||
// seems silly to allow deletion but not insertion, so include them here too.)
 | 
			
		||||
template <typename Vector, typename Class_>
 | 
			
		||||
void vector_modifiers(
 | 
			
		||||
    enable_if_t<is_copy_constructible<typename Vector::value_type>::value, Class_> &cl) {
 | 
			
		||||
    using T = typename Vector::value_type;
 | 
			
		||||
    using SizeType = typename Vector::size_type;
 | 
			
		||||
    using DiffType = typename Vector::difference_type;
 | 
			
		||||
 | 
			
		||||
    auto wrap_i = [](DiffType i, SizeType n) {
 | 
			
		||||
        if (i < 0) {
 | 
			
		||||
            i += n;
 | 
			
		||||
        }
 | 
			
		||||
        if (i < 0 || (SizeType) i >= n) {
 | 
			
		||||
            throw index_error();
 | 
			
		||||
        }
 | 
			
		||||
        return i;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    cl.def(
 | 
			
		||||
        "append",
 | 
			
		||||
        [](Vector &v, const T &value) { v.push_back(value); },
 | 
			
		||||
        arg("x"),
 | 
			
		||||
        "Add an item to the end of the list");
 | 
			
		||||
 | 
			
		||||
    cl.def(init([](const iterable &it) {
 | 
			
		||||
        auto v = std::unique_ptr<Vector>(new Vector());
 | 
			
		||||
        v->reserve(len_hint(it));
 | 
			
		||||
        for (handle h : it) {
 | 
			
		||||
            v->push_back(h.cast<T>());
 | 
			
		||||
        }
 | 
			
		||||
        return v.release();
 | 
			
		||||
    }));
 | 
			
		||||
 | 
			
		||||
    cl.def(
 | 
			
		||||
        "clear", [](Vector &v) { v.clear(); }, "Clear the contents");
 | 
			
		||||
 | 
			
		||||
    cl.def(
 | 
			
		||||
        "extend",
 | 
			
		||||
        [](Vector &v, const Vector &src) { v.insert(v.end(), src.begin(), src.end()); },
 | 
			
		||||
        arg("L"),
 | 
			
		||||
        "Extend the list by appending all the items in the given list");
 | 
			
		||||
 | 
			
		||||
    cl.def(
 | 
			
		||||
        "extend",
 | 
			
		||||
        [](Vector &v, const iterable &it) {
 | 
			
		||||
            const size_t old_size = v.size();
 | 
			
		||||
            v.reserve(old_size + len_hint(it));
 | 
			
		||||
            try {
 | 
			
		||||
                for (handle h : it) {
 | 
			
		||||
                    v.push_back(h.cast<T>());
 | 
			
		||||
                }
 | 
			
		||||
            } catch (const cast_error &) {
 | 
			
		||||
                v.erase(v.begin() + static_cast<typename Vector::difference_type>(old_size),
 | 
			
		||||
                        v.end());
 | 
			
		||||
                try {
 | 
			
		||||
                    v.shrink_to_fit();
 | 
			
		||||
                } catch (const std::exception &) {
 | 
			
		||||
                    // Do nothing
 | 
			
		||||
                }
 | 
			
		||||
                throw;
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        arg("L"),
 | 
			
		||||
        "Extend the list by appending all the items in the given list");
 | 
			
		||||
 | 
			
		||||
    cl.def(
 | 
			
		||||
        "insert",
 | 
			
		||||
        [](Vector &v, DiffType i, const T &x) {
 | 
			
		||||
            // Can't use wrap_i; i == v.size() is OK
 | 
			
		||||
            if (i < 0) {
 | 
			
		||||
                i += v.size();
 | 
			
		||||
            }
 | 
			
		||||
            if (i < 0 || (SizeType) i > v.size()) {
 | 
			
		||||
                throw index_error();
 | 
			
		||||
            }
 | 
			
		||||
            v.insert(v.begin() + i, x);
 | 
			
		||||
        },
 | 
			
		||||
        arg("i"),
 | 
			
		||||
        arg("x"),
 | 
			
		||||
        "Insert an item at a given position.");
 | 
			
		||||
 | 
			
		||||
    cl.def(
 | 
			
		||||
        "pop",
 | 
			
		||||
        [](Vector &v) {
 | 
			
		||||
            if (v.empty()) {
 | 
			
		||||
                throw index_error();
 | 
			
		||||
            }
 | 
			
		||||
            T t = std::move(v.back());
 | 
			
		||||
            v.pop_back();
 | 
			
		||||
            return t;
 | 
			
		||||
        },
 | 
			
		||||
        "Remove and return the last item");
 | 
			
		||||
 | 
			
		||||
    cl.def(
 | 
			
		||||
        "pop",
 | 
			
		||||
        [wrap_i](Vector &v, DiffType i) {
 | 
			
		||||
            i = wrap_i(i, v.size());
 | 
			
		||||
            T t = std::move(v[(SizeType) i]);
 | 
			
		||||
            v.erase(std::next(v.begin(), i));
 | 
			
		||||
            return t;
 | 
			
		||||
        },
 | 
			
		||||
        arg("i"),
 | 
			
		||||
        "Remove and return the item at index ``i``");
 | 
			
		||||
 | 
			
		||||
    cl.def("__setitem__", [wrap_i](Vector &v, DiffType i, const T &t) {
 | 
			
		||||
        i = wrap_i(i, v.size());
 | 
			
		||||
        v[(SizeType) i] = t;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    /// Slicing protocol
 | 
			
		||||
    cl.def(
 | 
			
		||||
        "__getitem__",
 | 
			
		||||
        [](const Vector &v, const slice &slice) -> Vector * {
 | 
			
		||||
            size_t start = 0, stop = 0, step = 0, slicelength = 0;
 | 
			
		||||
 | 
			
		||||
            if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) {
 | 
			
		||||
                throw error_already_set();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            auto *seq = new Vector();
 | 
			
		||||
            seq->reserve((size_t) slicelength);
 | 
			
		||||
 | 
			
		||||
            for (size_t i = 0; i < slicelength; ++i) {
 | 
			
		||||
                seq->push_back(v[start]);
 | 
			
		||||
                start += step;
 | 
			
		||||
            }
 | 
			
		||||
            return seq;
 | 
			
		||||
        },
 | 
			
		||||
        arg("s"),
 | 
			
		||||
        "Retrieve list elements using a slice object");
 | 
			
		||||
 | 
			
		||||
    cl.def(
 | 
			
		||||
        "__setitem__",
 | 
			
		||||
        [](Vector &v, const slice &slice, const Vector &value) {
 | 
			
		||||
            size_t start = 0, stop = 0, step = 0, slicelength = 0;
 | 
			
		||||
            if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) {
 | 
			
		||||
                throw error_already_set();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (slicelength != value.size()) {
 | 
			
		||||
                throw std::runtime_error(
 | 
			
		||||
                    "Left and right hand size of slice assignment have different sizes!");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            for (size_t i = 0; i < slicelength; ++i) {
 | 
			
		||||
                v[start] = value[i];
 | 
			
		||||
                start += step;
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "Assign list elements using a slice object");
 | 
			
		||||
 | 
			
		||||
    cl.def(
 | 
			
		||||
        "__delitem__",
 | 
			
		||||
        [wrap_i](Vector &v, DiffType i) {
 | 
			
		||||
            i = wrap_i(i, v.size());
 | 
			
		||||
            v.erase(v.begin() + i);
 | 
			
		||||
        },
 | 
			
		||||
        "Delete the list elements at index ``i``");
 | 
			
		||||
 | 
			
		||||
    cl.def(
 | 
			
		||||
        "__delitem__",
 | 
			
		||||
        [](Vector &v, const slice &slice) {
 | 
			
		||||
            size_t start = 0, stop = 0, step = 0, slicelength = 0;
 | 
			
		||||
 | 
			
		||||
            if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) {
 | 
			
		||||
                throw error_already_set();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (step == 1 && false) {
 | 
			
		||||
                v.erase(v.begin() + (DiffType) start, v.begin() + DiffType(start + slicelength));
 | 
			
		||||
            } else {
 | 
			
		||||
                for (size_t i = 0; i < slicelength; ++i) {
 | 
			
		||||
                    v.erase(v.begin() + DiffType(start));
 | 
			
		||||
                    start += step - 1;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "Delete list elements using a slice object");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// If the type has an operator[] that doesn't return a reference (most notably std::vector<bool>),
 | 
			
		||||
// we have to access by copying; otherwise we return by reference.
 | 
			
		||||
template <typename Vector>
 | 
			
		||||
using vector_needs_copy
 | 
			
		||||
    = negation<std::is_same<decltype(std::declval<Vector>()[typename Vector::size_type()]),
 | 
			
		||||
                            typename Vector::value_type &>>;
 | 
			
		||||
 | 
			
		||||
// The usual case: access and iterate by reference
 | 
			
		||||
template <typename Vector, typename Class_>
 | 
			
		||||
void vector_accessor(enable_if_t<!vector_needs_copy<Vector>::value, Class_> &cl) {
 | 
			
		||||
    using T = typename Vector::value_type;
 | 
			
		||||
    using SizeType = typename Vector::size_type;
 | 
			
		||||
    using DiffType = typename Vector::difference_type;
 | 
			
		||||
    using ItType = typename Vector::iterator;
 | 
			
		||||
 | 
			
		||||
    auto wrap_i = [](DiffType i, SizeType n) {
 | 
			
		||||
        if (i < 0) {
 | 
			
		||||
            i += n;
 | 
			
		||||
        }
 | 
			
		||||
        if (i < 0 || (SizeType) i >= n) {
 | 
			
		||||
            throw index_error();
 | 
			
		||||
        }
 | 
			
		||||
        return i;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    cl.def(
 | 
			
		||||
        "__getitem__",
 | 
			
		||||
        [wrap_i](Vector &v, DiffType i) -> T & {
 | 
			
		||||
            i = wrap_i(i, v.size());
 | 
			
		||||
            return v[(SizeType) i];
 | 
			
		||||
        },
 | 
			
		||||
        return_value_policy::reference_internal // ref + keepalive
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    cl.def(
 | 
			
		||||
        "__iter__",
 | 
			
		||||
        [](Vector &v) {
 | 
			
		||||
            return make_iterator<return_value_policy::reference_internal, ItType, ItType, T &>(
 | 
			
		||||
                v.begin(), v.end());
 | 
			
		||||
        },
 | 
			
		||||
        keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// The case for special objects, like std::vector<bool>, that have to be returned-by-copy:
 | 
			
		||||
template <typename Vector, typename Class_>
 | 
			
		||||
void vector_accessor(enable_if_t<vector_needs_copy<Vector>::value, Class_> &cl) {
 | 
			
		||||
    using T = typename Vector::value_type;
 | 
			
		||||
    using SizeType = typename Vector::size_type;
 | 
			
		||||
    using DiffType = typename Vector::difference_type;
 | 
			
		||||
    using ItType = typename Vector::iterator;
 | 
			
		||||
    cl.def("__getitem__", [](const Vector &v, DiffType i) -> T {
 | 
			
		||||
        if (i < 0) {
 | 
			
		||||
            i += v.size();
 | 
			
		||||
            if (i < 0) {
 | 
			
		||||
                throw index_error();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        auto i_st = static_cast<SizeType>(i);
 | 
			
		||||
        if (i_st >= v.size()) {
 | 
			
		||||
            throw index_error();
 | 
			
		||||
        }
 | 
			
		||||
        return v[i_st];
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    cl.def(
 | 
			
		||||
        "__iter__",
 | 
			
		||||
        [](Vector &v) {
 | 
			
		||||
            return make_iterator<return_value_policy::copy, ItType, ItType, T>(v.begin(), v.end());
 | 
			
		||||
        },
 | 
			
		||||
        keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Vector, typename Class_>
 | 
			
		||||
auto vector_if_insertion_operator(Class_ &cl, std::string const &name)
 | 
			
		||||
    -> decltype(std::declval<std::ostream &>() << std::declval<typename Vector::value_type>(),
 | 
			
		||||
                void()) {
 | 
			
		||||
    using size_type = typename Vector::size_type;
 | 
			
		||||
 | 
			
		||||
    cl.def(
 | 
			
		||||
        "__repr__",
 | 
			
		||||
        [name](Vector &v) {
 | 
			
		||||
            std::ostringstream s;
 | 
			
		||||
            s << name << '[';
 | 
			
		||||
            for (size_type i = 0; i < v.size(); ++i) {
 | 
			
		||||
                s << v[i];
 | 
			
		||||
                if (i != v.size() - 1) {
 | 
			
		||||
                    s << ", ";
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            s << ']';
 | 
			
		||||
            return s.str();
 | 
			
		||||
        },
 | 
			
		||||
        "Return the canonical string representation of this list.");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Provide the buffer interface for vectors if we have data() and we have a format for it
 | 
			
		||||
// GCC seems to have "void std::vector<bool>::data()" - doing SFINAE on the existence of data()
 | 
			
		||||
// is insufficient, we need to check it returns an appropriate pointer
 | 
			
		||||
template <typename Vector, typename = void>
 | 
			
		||||
struct vector_has_data_and_format : std::false_type {};
 | 
			
		||||
template <typename Vector>
 | 
			
		||||
struct vector_has_data_and_format<
 | 
			
		||||
    Vector,
 | 
			
		||||
    enable_if_t<std::is_same<decltype(format_descriptor<typename Vector::value_type>::format(),
 | 
			
		||||
                                      std::declval<Vector>().data()),
 | 
			
		||||
                             typename Vector::value_type *>::value>> : std::true_type {};
 | 
			
		||||
 | 
			
		||||
// [workaround(intel)] Separate function required here
 | 
			
		||||
// Workaround as the Intel compiler does not compile the enable_if_t part below
 | 
			
		||||
// (tested with icc (ICC) 2021.1 Beta 20200827)
 | 
			
		||||
template <typename... Args>
 | 
			
		||||
constexpr bool args_any_are_buffer() {
 | 
			
		||||
    return detail::any_of<std::is_same<Args, buffer_protocol>...>::value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// [workaround(intel)] Separate function required here
 | 
			
		||||
// [workaround(msvc)] Can't use constexpr bool in return type
 | 
			
		||||
 | 
			
		||||
// Add the buffer interface to a vector
 | 
			
		||||
template <typename Vector, typename Class_, typename... Args>
 | 
			
		||||
void vector_buffer_impl(Class_ &cl, std::true_type) {
 | 
			
		||||
    using T = typename Vector::value_type;
 | 
			
		||||
 | 
			
		||||
    static_assert(vector_has_data_and_format<Vector>::value,
 | 
			
		||||
                  "There is not an appropriate format descriptor for this vector");
 | 
			
		||||
 | 
			
		||||
    // numpy.h declares this for arbitrary types, but it may raise an exception and crash hard
 | 
			
		||||
    // at runtime if PYBIND11_NUMPY_DTYPE hasn't been called, so check here
 | 
			
		||||
    format_descriptor<T>::format();
 | 
			
		||||
 | 
			
		||||
    cl.def_buffer([](Vector &v) -> buffer_info {
 | 
			
		||||
        return buffer_info(v.data(),
 | 
			
		||||
                           static_cast<ssize_t>(sizeof(T)),
 | 
			
		||||
                           format_descriptor<T>::format(),
 | 
			
		||||
                           1,
 | 
			
		||||
                           {v.size()},
 | 
			
		||||
                           {sizeof(T)});
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    cl.def(init([](const buffer &buf) {
 | 
			
		||||
        auto info = buf.request();
 | 
			
		||||
        if (info.ndim != 1 || info.strides[0] % static_cast<ssize_t>(sizeof(T))) {
 | 
			
		||||
            throw type_error("Only valid 1D buffers can be copied to a vector");
 | 
			
		||||
        }
 | 
			
		||||
        if (!detail::compare_buffer_info<T>::compare(info)
 | 
			
		||||
            || (ssize_t) sizeof(T) != info.itemsize) {
 | 
			
		||||
            throw type_error("Format mismatch (Python: " + info.format
 | 
			
		||||
                             + " C++: " + format_descriptor<T>::format() + ")");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        T *p = static_cast<T *>(info.ptr);
 | 
			
		||||
        ssize_t step = info.strides[0] / static_cast<ssize_t>(sizeof(T));
 | 
			
		||||
        T *end = p + info.shape[0] * step;
 | 
			
		||||
        if (step == 1) {
 | 
			
		||||
            return Vector(p, end);
 | 
			
		||||
        }
 | 
			
		||||
        Vector vec;
 | 
			
		||||
        vec.reserve((size_t) info.shape[0]);
 | 
			
		||||
        for (; p != end; p += step) {
 | 
			
		||||
            vec.push_back(*p);
 | 
			
		||||
        }
 | 
			
		||||
        return vec;
 | 
			
		||||
    }));
 | 
			
		||||
 | 
			
		||||
    return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Vector, typename Class_, typename... Args>
 | 
			
		||||
void vector_buffer_impl(Class_ &, std::false_type) {}
 | 
			
		||||
 | 
			
		||||
template <typename Vector, typename Class_, typename... Args>
 | 
			
		||||
void vector_buffer(Class_ &cl) {
 | 
			
		||||
    vector_buffer_impl<Vector, Class_, Args...>(
 | 
			
		||||
        cl, detail::any_of<std::is_same<Args, buffer_protocol>...>{});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_END(detail)
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// std::vector
 | 
			
		||||
//
 | 
			
		||||
template <typename Vector, typename holder_type = std::unique_ptr<Vector>, typename... Args>
 | 
			
		||||
class_<Vector, holder_type> bind_vector(handle scope, std::string const &name, Args &&...args) {
 | 
			
		||||
    using Class_ = class_<Vector, holder_type>;
 | 
			
		||||
 | 
			
		||||
    // If the value_type is unregistered (e.g. a converting type) or is itself registered
 | 
			
		||||
    // module-local then make the vector binding module-local as well:
 | 
			
		||||
    using vtype = typename Vector::value_type;
 | 
			
		||||
    auto *vtype_info = detail::get_type_info(typeid(vtype));
 | 
			
		||||
    bool local = !vtype_info || vtype_info->module_local;
 | 
			
		||||
 | 
			
		||||
    Class_ cl(scope, name.c_str(), pybind11::module_local(local), std::forward<Args>(args)...);
 | 
			
		||||
 | 
			
		||||
    // Declare the buffer interface if a buffer_protocol() is passed in
 | 
			
		||||
    detail::vector_buffer<Vector, Class_, Args...>(cl);
 | 
			
		||||
 | 
			
		||||
    cl.def(init<>());
 | 
			
		||||
 | 
			
		||||
    // Register copy constructor (if possible)
 | 
			
		||||
    detail::vector_if_copy_constructible<Vector, Class_>(cl);
 | 
			
		||||
 | 
			
		||||
    // Register comparison-related operators and functions (if possible)
 | 
			
		||||
    detail::vector_if_equal_operator<Vector, Class_>(cl);
 | 
			
		||||
 | 
			
		||||
    // Register stream insertion operator (if possible)
 | 
			
		||||
    detail::vector_if_insertion_operator<Vector, Class_>(cl, name);
 | 
			
		||||
 | 
			
		||||
    // Modifiers require copyable vector value type
 | 
			
		||||
    detail::vector_modifiers<Vector, Class_>(cl);
 | 
			
		||||
 | 
			
		||||
    // Accessor and iterator; return by value if copyable, otherwise we return by ref + keep-alive
 | 
			
		||||
    detail::vector_accessor<Vector, Class_>(cl);
 | 
			
		||||
 | 
			
		||||
    cl.def(
 | 
			
		||||
        "__bool__",
 | 
			
		||||
        [](const Vector &v) -> bool { return !v.empty(); },
 | 
			
		||||
        "Check whether the list is nonempty");
 | 
			
		||||
 | 
			
		||||
    cl.def("__len__", &Vector::size);
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
    // C++ style functions deprecated, leaving it here as an example
 | 
			
		||||
    cl.def(init<size_type>());
 | 
			
		||||
 | 
			
		||||
    cl.def("resize",
 | 
			
		||||
         (void (Vector::*) (size_type count)) & Vector::resize,
 | 
			
		||||
         "changes the number of elements stored");
 | 
			
		||||
 | 
			
		||||
    cl.def("erase",
 | 
			
		||||
        [](Vector &v, SizeType i) {
 | 
			
		||||
        if (i >= v.size())
 | 
			
		||||
            throw index_error();
 | 
			
		||||
        v.erase(v.begin() + i);
 | 
			
		||||
    }, "erases element at index ``i``");
 | 
			
		||||
 | 
			
		||||
    cl.def("empty",         &Vector::empty,         "checks whether the container is empty");
 | 
			
		||||
    cl.def("size",          &Vector::size,          "returns the number of elements");
 | 
			
		||||
    cl.def("push_back", (void (Vector::*)(const T&)) &Vector::push_back, "adds an element to the end");
 | 
			
		||||
    cl.def("pop_back",                               &Vector::pop_back, "removes the last element");
 | 
			
		||||
 | 
			
		||||
    cl.def("max_size",      &Vector::max_size,      "returns the maximum possible number of elements");
 | 
			
		||||
    cl.def("reserve",       &Vector::reserve,       "reserves storage");
 | 
			
		||||
    cl.def("capacity",      &Vector::capacity,      "returns the number of elements that can be held in currently allocated storage");
 | 
			
		||||
    cl.def("shrink_to_fit", &Vector::shrink_to_fit, "reduces memory usage by freeing unused memory");
 | 
			
		||||
 | 
			
		||||
    cl.def("clear", &Vector::clear, "clears the contents");
 | 
			
		||||
    cl.def("swap",   &Vector::swap, "swaps the contents");
 | 
			
		||||
 | 
			
		||||
    cl.def("front", [](Vector &v) {
 | 
			
		||||
        if (v.size()) return v.front();
 | 
			
		||||
        else throw index_error();
 | 
			
		||||
    }, "access the first element");
 | 
			
		||||
 | 
			
		||||
    cl.def("back", [](Vector &v) {
 | 
			
		||||
        if (v.size()) return v.back();
 | 
			
		||||
        else throw index_error();
 | 
			
		||||
    }, "access the last element ");
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    return cl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// std::map, std::unordered_map
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(detail)
 | 
			
		||||
 | 
			
		||||
/* Fallback functions */
 | 
			
		||||
template <typename, typename, typename... Args>
 | 
			
		||||
void map_if_insertion_operator(const Args &...) {}
 | 
			
		||||
template <typename, typename, typename... Args>
 | 
			
		||||
void map_assignment(const Args &...) {}
 | 
			
		||||
 | 
			
		||||
// Map assignment when copy-assignable: just copy the value
 | 
			
		||||
template <typename Map, typename Class_>
 | 
			
		||||
void map_assignment(
 | 
			
		||||
    enable_if_t<is_copy_assignable<typename Map::mapped_type>::value, Class_> &cl) {
 | 
			
		||||
    using KeyType = typename Map::key_type;
 | 
			
		||||
    using MappedType = typename Map::mapped_type;
 | 
			
		||||
 | 
			
		||||
    cl.def("__setitem__", [](Map &m, const KeyType &k, const MappedType &v) {
 | 
			
		||||
        auto it = m.find(k);
 | 
			
		||||
        if (it != m.end()) {
 | 
			
		||||
            it->second = v;
 | 
			
		||||
        } else {
 | 
			
		||||
            m.emplace(k, v);
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Not copy-assignable, but still copy-constructible: we can update the value by erasing and
 | 
			
		||||
// reinserting
 | 
			
		||||
template <typename Map, typename Class_>
 | 
			
		||||
void map_assignment(enable_if_t<!is_copy_assignable<typename Map::mapped_type>::value
 | 
			
		||||
                                    && is_copy_constructible<typename Map::mapped_type>::value,
 | 
			
		||||
                                Class_> &cl) {
 | 
			
		||||
    using KeyType = typename Map::key_type;
 | 
			
		||||
    using MappedType = typename Map::mapped_type;
 | 
			
		||||
 | 
			
		||||
    cl.def("__setitem__", [](Map &m, const KeyType &k, const MappedType &v) {
 | 
			
		||||
        // We can't use m[k] = v; because value type might not be default constructable
 | 
			
		||||
        auto r = m.emplace(k, v);
 | 
			
		||||
        if (!r.second) {
 | 
			
		||||
            // value type is not copy assignable so the only way to insert it is to erase it
 | 
			
		||||
            // first...
 | 
			
		||||
            m.erase(r.first);
 | 
			
		||||
            m.emplace(k, v);
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Map, typename Class_>
 | 
			
		||||
auto map_if_insertion_operator(Class_ &cl, std::string const &name)
 | 
			
		||||
    -> decltype(std::declval<std::ostream &>() << std::declval<typename Map::key_type>()
 | 
			
		||||
                                               << std::declval<typename Map::mapped_type>(),
 | 
			
		||||
                void()) {
 | 
			
		||||
 | 
			
		||||
    cl.def(
 | 
			
		||||
        "__repr__",
 | 
			
		||||
        [name](Map &m) {
 | 
			
		||||
            std::ostringstream s;
 | 
			
		||||
            s << name << '{';
 | 
			
		||||
            bool f = false;
 | 
			
		||||
            for (auto const &kv : m) {
 | 
			
		||||
                if (f) {
 | 
			
		||||
                    s << ", ";
 | 
			
		||||
                }
 | 
			
		||||
                s << kv.first << ": " << kv.second;
 | 
			
		||||
                f = true;
 | 
			
		||||
            }
 | 
			
		||||
            s << '}';
 | 
			
		||||
            return s.str();
 | 
			
		||||
        },
 | 
			
		||||
        "Return the canonical string representation of this map.");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename KeyType>
 | 
			
		||||
struct keys_view {
 | 
			
		||||
    virtual size_t len() = 0;
 | 
			
		||||
    virtual iterator iter() = 0;
 | 
			
		||||
    virtual bool contains(const KeyType &k) = 0;
 | 
			
		||||
    virtual bool contains(const object &k) = 0;
 | 
			
		||||
    virtual ~keys_view() = default;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename MappedType>
 | 
			
		||||
struct values_view {
 | 
			
		||||
    virtual size_t len() = 0;
 | 
			
		||||
    virtual iterator iter() = 0;
 | 
			
		||||
    virtual ~values_view() = default;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename KeyType, typename MappedType>
 | 
			
		||||
struct items_view {
 | 
			
		||||
    virtual size_t len() = 0;
 | 
			
		||||
    virtual iterator iter() = 0;
 | 
			
		||||
    virtual ~items_view() = default;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename Map, typename KeysView>
 | 
			
		||||
struct KeysViewImpl : public KeysView {
 | 
			
		||||
    explicit KeysViewImpl(Map &map) : map(map) {}
 | 
			
		||||
    size_t len() override { return map.size(); }
 | 
			
		||||
    iterator iter() override { return make_key_iterator(map.begin(), map.end()); }
 | 
			
		||||
    bool contains(const typename Map::key_type &k) override { return map.find(k) != map.end(); }
 | 
			
		||||
    bool contains(const object &) override { return false; }
 | 
			
		||||
    Map ↦
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename Map, typename ValuesView>
 | 
			
		||||
struct ValuesViewImpl : public ValuesView {
 | 
			
		||||
    explicit ValuesViewImpl(Map &map) : map(map) {}
 | 
			
		||||
    size_t len() override { return map.size(); }
 | 
			
		||||
    iterator iter() override { return make_value_iterator(map.begin(), map.end()); }
 | 
			
		||||
    Map ↦
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename Map, typename ItemsView>
 | 
			
		||||
struct ItemsViewImpl : public ItemsView {
 | 
			
		||||
    explicit ItemsViewImpl(Map &map) : map(map) {}
 | 
			
		||||
    size_t len() override { return map.size(); }
 | 
			
		||||
    iterator iter() override { return make_iterator(map.begin(), map.end()); }
 | 
			
		||||
    Map ↦
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_END(detail)
 | 
			
		||||
 | 
			
		||||
template <typename Map, typename holder_type = std::unique_ptr<Map>, typename... Args>
 | 
			
		||||
class_<Map, holder_type> bind_map(handle scope, const std::string &name, Args &&...args) {
 | 
			
		||||
    using KeyType = typename Map::key_type;
 | 
			
		||||
    using MappedType = typename Map::mapped_type;
 | 
			
		||||
    using StrippedKeyType = detail::remove_cvref_t<KeyType>;
 | 
			
		||||
    using StrippedMappedType = detail::remove_cvref_t<MappedType>;
 | 
			
		||||
    using KeysView = detail::keys_view<StrippedKeyType>;
 | 
			
		||||
    using ValuesView = detail::values_view<StrippedMappedType>;
 | 
			
		||||
    using ItemsView = detail::items_view<StrippedKeyType, StrippedMappedType>;
 | 
			
		||||
    using Class_ = class_<Map, holder_type>;
 | 
			
		||||
 | 
			
		||||
    // If either type is a non-module-local bound type then make the map binding non-local as well;
 | 
			
		||||
    // otherwise (e.g. both types are either module-local or converting) the map will be
 | 
			
		||||
    // module-local.
 | 
			
		||||
    auto *tinfo = detail::get_type_info(typeid(MappedType));
 | 
			
		||||
    bool local = !tinfo || tinfo->module_local;
 | 
			
		||||
    if (local) {
 | 
			
		||||
        tinfo = detail::get_type_info(typeid(KeyType));
 | 
			
		||||
        local = !tinfo || tinfo->module_local;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Class_ cl(scope, name.c_str(), pybind11::module_local(local), std::forward<Args>(args)...);
 | 
			
		||||
    static constexpr auto key_type_descr = detail::make_caster<KeyType>::name;
 | 
			
		||||
    static constexpr auto mapped_type_descr = detail::make_caster<MappedType>::name;
 | 
			
		||||
    std::string key_type_name(key_type_descr.text), mapped_type_name(mapped_type_descr.text);
 | 
			
		||||
 | 
			
		||||
    // If key type isn't properly wrapped, fall back to C++ names
 | 
			
		||||
    if (key_type_name == "%") {
 | 
			
		||||
        key_type_name = detail::type_info_description(typeid(KeyType));
 | 
			
		||||
    }
 | 
			
		||||
    // Similarly for value type:
 | 
			
		||||
    if (mapped_type_name == "%") {
 | 
			
		||||
        mapped_type_name = detail::type_info_description(typeid(MappedType));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Wrap KeysView[KeyType] if it wasn't already wrapped
 | 
			
		||||
    if (!detail::get_type_info(typeid(KeysView))) {
 | 
			
		||||
        class_<KeysView> keys_view(
 | 
			
		||||
            scope, ("KeysView[" + key_type_name + "]").c_str(), pybind11::module_local(local));
 | 
			
		||||
        keys_view.def("__len__", &KeysView::len);
 | 
			
		||||
        keys_view.def("__iter__",
 | 
			
		||||
                      &KeysView::iter,
 | 
			
		||||
                      keep_alive<0, 1>() /* Essential: keep view alive while iterator exists */
 | 
			
		||||
        );
 | 
			
		||||
        keys_view.def("__contains__",
 | 
			
		||||
                      static_cast<bool (KeysView::*)(const KeyType &)>(&KeysView::contains));
 | 
			
		||||
        // Fallback for when the object is not of the key type
 | 
			
		||||
        keys_view.def("__contains__",
 | 
			
		||||
                      static_cast<bool (KeysView::*)(const object &)>(&KeysView::contains));
 | 
			
		||||
    }
 | 
			
		||||
    // Similarly for ValuesView:
 | 
			
		||||
    if (!detail::get_type_info(typeid(ValuesView))) {
 | 
			
		||||
        class_<ValuesView> values_view(scope,
 | 
			
		||||
                                       ("ValuesView[" + mapped_type_name + "]").c_str(),
 | 
			
		||||
                                       pybind11::module_local(local));
 | 
			
		||||
        values_view.def("__len__", &ValuesView::len);
 | 
			
		||||
        values_view.def("__iter__",
 | 
			
		||||
                        &ValuesView::iter,
 | 
			
		||||
                        keep_alive<0, 1>() /* Essential: keep view alive while iterator exists */
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    // Similarly for ItemsView:
 | 
			
		||||
    if (!detail::get_type_info(typeid(ItemsView))) {
 | 
			
		||||
        class_<ItemsView> items_view(
 | 
			
		||||
            scope,
 | 
			
		||||
            ("ItemsView[" + key_type_name + ", ").append(mapped_type_name + "]").c_str(),
 | 
			
		||||
            pybind11::module_local(local));
 | 
			
		||||
        items_view.def("__len__", &ItemsView::len);
 | 
			
		||||
        items_view.def("__iter__",
 | 
			
		||||
                       &ItemsView::iter,
 | 
			
		||||
                       keep_alive<0, 1>() /* Essential: keep view alive while iterator exists */
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    cl.def(init<>());
 | 
			
		||||
 | 
			
		||||
    // Register stream insertion operator (if possible)
 | 
			
		||||
    detail::map_if_insertion_operator<Map, Class_>(cl, name);
 | 
			
		||||
 | 
			
		||||
    cl.def(
 | 
			
		||||
        "__bool__",
 | 
			
		||||
        [](const Map &m) -> bool { return !m.empty(); },
 | 
			
		||||
        "Check whether the map is nonempty");
 | 
			
		||||
 | 
			
		||||
    cl.def(
 | 
			
		||||
        "__iter__",
 | 
			
		||||
        [](Map &m) { return make_key_iterator(m.begin(), m.end()); },
 | 
			
		||||
        keep_alive<0, 1>() /* Essential: keep map alive while iterator exists */
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    cl.def(
 | 
			
		||||
        "keys",
 | 
			
		||||
        [](Map &m) {
 | 
			
		||||
            return std::unique_ptr<KeysView>(new detail::KeysViewImpl<Map, KeysView>(m));
 | 
			
		||||
        },
 | 
			
		||||
        keep_alive<0, 1>() /* Essential: keep map alive while view exists */
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    cl.def(
 | 
			
		||||
        "values",
 | 
			
		||||
        [](Map &m) {
 | 
			
		||||
            return std::unique_ptr<ValuesView>(new detail::ValuesViewImpl<Map, ValuesView>(m));
 | 
			
		||||
        },
 | 
			
		||||
        keep_alive<0, 1>() /* Essential: keep map alive while view exists */
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    cl.def(
 | 
			
		||||
        "items",
 | 
			
		||||
        [](Map &m) {
 | 
			
		||||
            return std::unique_ptr<ItemsView>(new detail::ItemsViewImpl<Map, ItemsView>(m));
 | 
			
		||||
        },
 | 
			
		||||
        keep_alive<0, 1>() /* Essential: keep map alive while view exists */
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    cl.def(
 | 
			
		||||
        "__getitem__",
 | 
			
		||||
        [](Map &m, const KeyType &k) -> MappedType & {
 | 
			
		||||
            auto it = m.find(k);
 | 
			
		||||
            if (it == m.end()) {
 | 
			
		||||
                throw key_error();
 | 
			
		||||
            }
 | 
			
		||||
            return it->second;
 | 
			
		||||
        },
 | 
			
		||||
        return_value_policy::reference_internal // ref + keepalive
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    cl.def("__contains__", [](Map &m, const KeyType &k) -> bool {
 | 
			
		||||
        auto it = m.find(k);
 | 
			
		||||
        if (it == m.end()) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    });
 | 
			
		||||
    // Fallback for when the object is not of the key type
 | 
			
		||||
    cl.def("__contains__", [](Map &, const object &) -> bool { return false; });
 | 
			
		||||
 | 
			
		||||
    // Assignment provided only if the type is copyable
 | 
			
		||||
    detail::map_assignment<Map, Class_>(cl);
 | 
			
		||||
 | 
			
		||||
    cl.def("__delitem__", [](Map &m, const KeyType &k) {
 | 
			
		||||
        auto it = m.find(k);
 | 
			
		||||
        if (it == m.end()) {
 | 
			
		||||
            throw key_error();
 | 
			
		||||
        }
 | 
			
		||||
        m.erase(it);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    cl.def("__len__", &Map::size);
 | 
			
		||||
 | 
			
		||||
    return cl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
 | 
			
		||||
							
								
								
									
										61
									
								
								3rdparty/pybind11/include/pybind11/type_caster_pyobject_ptr.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								3rdparty/pybind11/include/pybind11/type_caster_pyobject_ptr.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
			
		||||
// Copyright (c) 2023 The pybind Community.
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "detail/common.h"
 | 
			
		||||
#include "detail/descr.h"
 | 
			
		||||
#include "cast.h"
 | 
			
		||||
#include "pytypes.h"
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
 | 
			
		||||
PYBIND11_NAMESPACE_BEGIN(detail)
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
class type_caster<PyObject> {
 | 
			
		||||
public:
 | 
			
		||||
    static constexpr auto name = const_name("object"); // See discussion under PR #4601.
 | 
			
		||||
 | 
			
		||||
    // This overload is purely to guard against accidents.
 | 
			
		||||
    template <typename T,
 | 
			
		||||
              detail::enable_if_t<!is_same_ignoring_cvref<T, PyObject *>::value, int> = 0>
 | 
			
		||||
    static handle cast(T &&, return_value_policy, handle /*parent*/) {
 | 
			
		||||
        static_assert(is_same_ignoring_cvref<T, PyObject *>::value,
 | 
			
		||||
                      "Invalid C++ type T for to-Python conversion (type_caster<PyObject>).");
 | 
			
		||||
        return nullptr; // Unreachable.
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static handle cast(PyObject *src, return_value_policy policy, handle /*parent*/) {
 | 
			
		||||
        if (src == nullptr) {
 | 
			
		||||
            throw error_already_set();
 | 
			
		||||
        }
 | 
			
		||||
        if (PyErr_Occurred()) {
 | 
			
		||||
            raise_from(PyExc_SystemError, "src != nullptr but PyErr_Occurred()");
 | 
			
		||||
            throw error_already_set();
 | 
			
		||||
        }
 | 
			
		||||
        if (policy == return_value_policy::take_ownership) {
 | 
			
		||||
            return src;
 | 
			
		||||
        }
 | 
			
		||||
        if (policy == return_value_policy::reference
 | 
			
		||||
            || policy == return_value_policy::automatic_reference) {
 | 
			
		||||
            return handle(src).inc_ref();
 | 
			
		||||
        }
 | 
			
		||||
        pybind11_fail("type_caster<PyObject>::cast(): unsupported return_value_policy: "
 | 
			
		||||
                      + std::to_string(static_cast<int>(policy)));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool load(handle src, bool) {
 | 
			
		||||
        value = reinterpret_borrow<object>(src);
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    using cast_op_type = PyObject *;
 | 
			
		||||
 | 
			
		||||
    explicit operator PyObject *() { return value.ptr(); }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    object value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
PYBIND11_NAMESPACE_END(detail)
 | 
			
		||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
 | 
			
		||||
							
								
								
									
										284
									
								
								3rdparty/waitingspinnerwidget.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										284
									
								
								3rdparty/waitingspinnerwidget.cpp
									
									
									
									
										vendored
									
									
								
							@@ -1,284 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 *   SPDX-FileCopyrightText: 2012-2014 Alexander Turkin
 | 
			
		||||
 *   SPDX-FileCopyrightText: 2014 William Hallatt
 | 
			
		||||
 *   SPDX-FileCopyrightText: 2015 Jacob Dawid
 | 
			
		||||
 *   SPDX-License-Identifier: MIT
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Original Work Copyright (c) 2012-2014 Alexander Turkin
 | 
			
		||||
   Modified 2014 by William Hallatt
 | 
			
		||||
   Modified 2015 by Jacob Dawid
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
the Software without restriction, including without limitation the rights to
 | 
			
		||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
subject to the following conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
// Own includes
 | 
			
		||||
#include "waitingspinnerwidget.h"
 | 
			
		||||
 | 
			
		||||
// Standard includes
 | 
			
		||||
#include <cmath>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
 | 
			
		||||
// Qt includes
 | 
			
		||||
#include <QPainter>
 | 
			
		||||
#include <QTimer>
 | 
			
		||||
 | 
			
		||||
WaitingSpinnerWidget::WaitingSpinnerWidget(QWidget *parent,
 | 
			
		||||
                                           bool centerOnParent,
 | 
			
		||||
                                           bool disableParentWhenSpinning)
 | 
			
		||||
    : QWidget(parent),
 | 
			
		||||
      _centerOnParent(centerOnParent),
 | 
			
		||||
      _disableParentWhenSpinning(disableParentWhenSpinning) {
 | 
			
		||||
    initialize();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
WaitingSpinnerWidget::WaitingSpinnerWidget(Qt::WindowModality modality,
 | 
			
		||||
                                           QWidget *parent,
 | 
			
		||||
                                           bool centerOnParent,
 | 
			
		||||
                                           bool disableParentWhenSpinning)
 | 
			
		||||
    : QWidget(parent, Qt::Dialog | Qt::FramelessWindowHint),
 | 
			
		||||
      _centerOnParent(centerOnParent),
 | 
			
		||||
      _disableParentWhenSpinning(disableParentWhenSpinning){
 | 
			
		||||
    initialize();
 | 
			
		||||
 | 
			
		||||
    // We need to set the window modality AFTER we've hidden the
 | 
			
		||||
    // widget for the first time since changing this property while
 | 
			
		||||
    // the widget is visible has no effect.
 | 
			
		||||
    setWindowModality(modality);
 | 
			
		||||
    setAttribute(Qt::WA_TranslucentBackground);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WaitingSpinnerWidget::initialize() {
 | 
			
		||||
    _color = Qt::black;
 | 
			
		||||
    _roundness = 100.0;
 | 
			
		||||
    _minimumTrailOpacity = 3.14159265358979323846;
 | 
			
		||||
    _trailFadePercentage = 80.0;
 | 
			
		||||
    _revolutionsPerSecond = 1.57079632679489661923;
 | 
			
		||||
    _numberOfLines = 20;
 | 
			
		||||
    _lineLength = 10;
 | 
			
		||||
    _lineWidth = 2;
 | 
			
		||||
    _innerRadius = 10;
 | 
			
		||||
    _currentCounter = 0;
 | 
			
		||||
    _isSpinning = false;
 | 
			
		||||
 | 
			
		||||
    _timer = new QTimer(this);
 | 
			
		||||
    connect(_timer, SIGNAL(timeout()), this, SLOT(rotate()));
 | 
			
		||||
    updateSize();
 | 
			
		||||
    updateTimer();
 | 
			
		||||
    hide();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WaitingSpinnerWidget::paintEvent(QPaintEvent *) {
 | 
			
		||||
    updatePosition();
 | 
			
		||||
    QPainter painter(this);
 | 
			
		||||
    painter.fillRect(this->rect(), Qt::transparent);
 | 
			
		||||
    painter.setRenderHint(QPainter::Antialiasing, true);
 | 
			
		||||
 | 
			
		||||
    if (_currentCounter >= _numberOfLines) {
 | 
			
		||||
        _currentCounter = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    painter.setPen(Qt::NoPen);
 | 
			
		||||
    for (int i = 0; i < _numberOfLines; ++i) {
 | 
			
		||||
        painter.save();
 | 
			
		||||
        painter.translate(_innerRadius + _lineLength,
 | 
			
		||||
                          _innerRadius + _lineLength);
 | 
			
		||||
        qreal rotateAngle =
 | 
			
		||||
                static_cast<qreal>(360 * i) / static_cast<qreal>(_numberOfLines);
 | 
			
		||||
        painter.rotate(rotateAngle);
 | 
			
		||||
        painter.translate(_innerRadius, 0);
 | 
			
		||||
        int distance =
 | 
			
		||||
                lineCountDistanceFromPrimary(i, _currentCounter, _numberOfLines);
 | 
			
		||||
        QColor color =
 | 
			
		||||
                currentLineColor(distance, _numberOfLines, _trailFadePercentage,
 | 
			
		||||
                                 _minimumTrailOpacity, _color);
 | 
			
		||||
        painter.setBrush(color);
 | 
			
		||||
        // TODO improve the way rounded rect is painted
 | 
			
		||||
        painter.drawRoundedRect(
 | 
			
		||||
                    QRect(0, -_lineWidth / 2, _lineLength, _lineWidth), _roundness,
 | 
			
		||||
                    _roundness, Qt::RelativeSize);
 | 
			
		||||
        painter.restore();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WaitingSpinnerWidget::start() {
 | 
			
		||||
    updatePosition();
 | 
			
		||||
    _isSpinning = true;
 | 
			
		||||
    show();
 | 
			
		||||
 | 
			
		||||
    if(parentWidget() && _disableParentWhenSpinning) {
 | 
			
		||||
        parentWidget()->setEnabled(false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!_timer->isActive()) {
 | 
			
		||||
        _timer->start();
 | 
			
		||||
        _currentCounter = 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WaitingSpinnerWidget::stop() {
 | 
			
		||||
    _isSpinning = false;
 | 
			
		||||
    hide();
 | 
			
		||||
 | 
			
		||||
    if(parentWidget() && _disableParentWhenSpinning) {
 | 
			
		||||
        parentWidget()->setEnabled(true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (_timer->isActive()) {
 | 
			
		||||
        _timer->stop();
 | 
			
		||||
        _currentCounter = 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WaitingSpinnerWidget::setNumberOfLines(int lines) {
 | 
			
		||||
    _numberOfLines = lines;
 | 
			
		||||
    _currentCounter = 0;
 | 
			
		||||
    updateTimer();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WaitingSpinnerWidget::setLineLength(int length) {
 | 
			
		||||
    _lineLength = length;
 | 
			
		||||
    updateSize();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WaitingSpinnerWidget::setLineWidth(int width) {
 | 
			
		||||
    _lineWidth = width;
 | 
			
		||||
    updateSize();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WaitingSpinnerWidget::setInnerRadius(int radius) {
 | 
			
		||||
    _innerRadius = radius;
 | 
			
		||||
    updateSize();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QColor WaitingSpinnerWidget::color() {
 | 
			
		||||
    return _color;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
qreal WaitingSpinnerWidget::roundness() {
 | 
			
		||||
    return _roundness;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
qreal WaitingSpinnerWidget::minimumTrailOpacity() {
 | 
			
		||||
    return _minimumTrailOpacity;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
qreal WaitingSpinnerWidget::trailFadePercentage() {
 | 
			
		||||
    return _trailFadePercentage;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
qreal WaitingSpinnerWidget::revolutionsPersSecond() {
 | 
			
		||||
    return _revolutionsPerSecond;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int WaitingSpinnerWidget::numberOfLines() {
 | 
			
		||||
    return _numberOfLines;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int WaitingSpinnerWidget::lineLength() {
 | 
			
		||||
    return _lineLength;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int WaitingSpinnerWidget::lineWidth() {
 | 
			
		||||
    return _lineWidth;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int WaitingSpinnerWidget::innerRadius() {
 | 
			
		||||
    return _innerRadius;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool WaitingSpinnerWidget::isSpinning() const {
 | 
			
		||||
    return _isSpinning;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WaitingSpinnerWidget::setRoundness(qreal roundness) {
 | 
			
		||||
    _roundness = std::max(0.0, std::min(100.0, roundness));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WaitingSpinnerWidget::setColor(QColor color) {
 | 
			
		||||
    _color = color;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WaitingSpinnerWidget::setRevolutionsPerSecond(qreal revolutionsPerSecond) {
 | 
			
		||||
    _revolutionsPerSecond = revolutionsPerSecond;
 | 
			
		||||
    updateTimer();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WaitingSpinnerWidget::setTrailFadePercentage(qreal trail) {
 | 
			
		||||
    _trailFadePercentage = trail;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WaitingSpinnerWidget::setMinimumTrailOpacity(qreal minimumTrailOpacity) {
 | 
			
		||||
    _minimumTrailOpacity = minimumTrailOpacity;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WaitingSpinnerWidget::rotate() {
 | 
			
		||||
    ++_currentCounter;
 | 
			
		||||
    if (_currentCounter >= _numberOfLines) {
 | 
			
		||||
        _currentCounter = 0;
 | 
			
		||||
    }
 | 
			
		||||
    update();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WaitingSpinnerWidget::updateSize() {
 | 
			
		||||
    int size = (_innerRadius + _lineLength) * 2;
 | 
			
		||||
    setFixedSize(size, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WaitingSpinnerWidget::updateTimer() {
 | 
			
		||||
    _timer->setInterval(1000 / (_numberOfLines * _revolutionsPerSecond));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WaitingSpinnerWidget::updatePosition() {
 | 
			
		||||
    if (parentWidget() && _centerOnParent) {
 | 
			
		||||
        move(parentWidget()->width() / 2 - width() / 2,
 | 
			
		||||
             parentWidget()->height() / 2 - height() / 2);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int WaitingSpinnerWidget::lineCountDistanceFromPrimary(int current, int primary,
 | 
			
		||||
                                                       int totalNrOfLines) {
 | 
			
		||||
    int distance = primary - current;
 | 
			
		||||
    if (distance < 0) {
 | 
			
		||||
        distance += totalNrOfLines;
 | 
			
		||||
    }
 | 
			
		||||
    return distance;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QColor WaitingSpinnerWidget::currentLineColor(int countDistance, int totalNrOfLines,
 | 
			
		||||
                                              qreal trailFadePerc, qreal minOpacity,
 | 
			
		||||
                                              QColor color) {
 | 
			
		||||
    if (countDistance == 0) {
 | 
			
		||||
        return color;
 | 
			
		||||
    }
 | 
			
		||||
    const qreal minAlphaF = minOpacity / 100.0;
 | 
			
		||||
    int distanceThreshold =
 | 
			
		||||
            static_cast<int>(ceil((totalNrOfLines - 1) * trailFadePerc / 100.0));
 | 
			
		||||
    if (countDistance > distanceThreshold) {
 | 
			
		||||
        color.setAlphaF(minAlphaF);
 | 
			
		||||
    } else {
 | 
			
		||||
        qreal alphaDiff = color.alphaF() - minAlphaF;
 | 
			
		||||
        qreal gradient = alphaDiff / static_cast<qreal>(distanceThreshold + 1);
 | 
			
		||||
        qreal resultAlpha = color.alphaF() - gradient * countDistance;
 | 
			
		||||
 | 
			
		||||
        // If alpha is out of bounds, clip it.
 | 
			
		||||
        resultAlpha = std::min(1.0, std::max(0.0, resultAlpha));
 | 
			
		||||
        color.setAlphaF(resultAlpha);
 | 
			
		||||
    }
 | 
			
		||||
    return color;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										122
									
								
								3rdparty/waitingspinnerwidget.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										122
									
								
								3rdparty/waitingspinnerwidget.h
									
									
									
									
										vendored
									
									
								
							@@ -1,122 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 *   SPDX-FileCopyrightText: 2012-2014 Alexander Turkin
 | 
			
		||||
 *   SPDX-FileCopyrightText: 2014 William Hallatt
 | 
			
		||||
 *   SPDX-FileCopyrightText: 2015 Jacob Dawid
 | 
			
		||||
 *   SPDX-License-Identifier: MIT
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Original Work Copyright (c) 2012-2014 Alexander Turkin
 | 
			
		||||
   Modified 2014 by William Hallatt
 | 
			
		||||
   Modified 2015 by Jacob Dawid
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
the Software without restriction, including without limitation the rights to
 | 
			
		||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
subject to the following conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
// Qt includes
 | 
			
		||||
#include <QWidget>
 | 
			
		||||
#include <QTimer>
 | 
			
		||||
#include <QColor>
 | 
			
		||||
 | 
			
		||||
class WaitingSpinnerWidget : public QWidget {
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
public:
 | 
			
		||||
    /*! Constructor for "standard" widget behaviour - use this
 | 
			
		||||
   * constructor if you wish to, e.g. embed your widget in another. */
 | 
			
		||||
    WaitingSpinnerWidget(QWidget *parent = nullptr,
 | 
			
		||||
                         bool centerOnParent = true,
 | 
			
		||||
                         bool disableParentWhenSpinning = true);
 | 
			
		||||
 | 
			
		||||
    /*! Constructor - use this constructor to automatically create a modal
 | 
			
		||||
   * ("blocking") spinner on top of the calling widget/window.  If a valid
 | 
			
		||||
   * parent widget is provided, "centreOnParent" will ensure that
 | 
			
		||||
   * QtWaitingSpinner automatically centres itself on it, if not,
 | 
			
		||||
   * "centreOnParent" is ignored. */
 | 
			
		||||
    WaitingSpinnerWidget(Qt::WindowModality modality,
 | 
			
		||||
                         QWidget *parent = nullptr,
 | 
			
		||||
                         bool centerOnParent = true,
 | 
			
		||||
                         bool disableParentWhenSpinning = true);
 | 
			
		||||
 | 
			
		||||
public slots:
 | 
			
		||||
    void start();
 | 
			
		||||
    void stop();
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    void setColor(QColor color);
 | 
			
		||||
    void setRoundness(qreal roundness);
 | 
			
		||||
    void setMinimumTrailOpacity(qreal minimumTrailOpacity);
 | 
			
		||||
    void setTrailFadePercentage(qreal trail);
 | 
			
		||||
    void setRevolutionsPerSecond(qreal revolutionsPerSecond);
 | 
			
		||||
    void setNumberOfLines(int lines);
 | 
			
		||||
    void setLineLength(int length);
 | 
			
		||||
    void setLineWidth(int width);
 | 
			
		||||
    void setInnerRadius(int radius);
 | 
			
		||||
    void setText(QString text);
 | 
			
		||||
 | 
			
		||||
    QColor color();
 | 
			
		||||
    qreal roundness();
 | 
			
		||||
    qreal minimumTrailOpacity();
 | 
			
		||||
    qreal trailFadePercentage();
 | 
			
		||||
    qreal revolutionsPersSecond();
 | 
			
		||||
    int numberOfLines();
 | 
			
		||||
    int lineLength();
 | 
			
		||||
    int lineWidth();
 | 
			
		||||
    int innerRadius();
 | 
			
		||||
 | 
			
		||||
    bool isSpinning() const;
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
    void rotate();
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    void paintEvent(QPaintEvent *paintEvent) override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    static int lineCountDistanceFromPrimary(int current, int primary,
 | 
			
		||||
                                            int totalNrOfLines);
 | 
			
		||||
    static QColor currentLineColor(int distance, int totalNrOfLines,
 | 
			
		||||
                                   qreal trailFadePerc, qreal minOpacity,
 | 
			
		||||
                                   QColor color);
 | 
			
		||||
 | 
			
		||||
    void initialize();
 | 
			
		||||
    void updateSize();
 | 
			
		||||
    void updateTimer();
 | 
			
		||||
    void updatePosition();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    QColor  _color;
 | 
			
		||||
    qreal   _roundness; // 0..100
 | 
			
		||||
    qreal   _minimumTrailOpacity;
 | 
			
		||||
    qreal   _trailFadePercentage;
 | 
			
		||||
    qreal   _revolutionsPerSecond;
 | 
			
		||||
    int     _numberOfLines;
 | 
			
		||||
    int     _lineLength;
 | 
			
		||||
    int     _lineWidth;
 | 
			
		||||
    int     _innerRadius;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    WaitingSpinnerWidget(const WaitingSpinnerWidget&);
 | 
			
		||||
    WaitingSpinnerWidget& operator=(const WaitingSpinnerWidget&);
 | 
			
		||||
 | 
			
		||||
    QTimer *_timer;
 | 
			
		||||
    bool    _centerOnParent;
 | 
			
		||||
    bool    _disableParentWhenSpinning;
 | 
			
		||||
    int     _currentCounter;
 | 
			
		||||
    bool    _isSpinning;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										29
									
								
								AUTHORS
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								AUTHORS
									
									
									
									
									
								
							@@ -20,29 +20,58 @@ and moral support from (alphabetically by first name or nickname):
 | 
			
		||||
 - Allen Welkie
 | 
			
		||||
 - AlmAck
 | 
			
		||||
 - Andrius Štikonas
 | 
			
		||||
 - Anke Boersma
 | 
			
		||||
 - Anubhav Choudhary
 | 
			
		||||
 - Arjen Balfoort
 | 
			
		||||
 - Arnaud Ferraris
 | 
			
		||||
 - Artem Grinev
 | 
			
		||||
 - artoo@cromnix.org
 | 
			
		||||
 - benne-dee
 | 
			
		||||
 - Bernhard Landauer
 | 
			
		||||
 - Bezzy1999
 | 
			
		||||
 - Bill Auger
 | 
			
		||||
 - Bob van der Linden
 | 
			
		||||
 - Caio Jordão Carvalho
 | 
			
		||||
 - Camilo Higuita
 | 
			
		||||
 - Collabora LTD
 | 
			
		||||
 - Corey Lang
 | 
			
		||||
 - crispg72
 | 
			
		||||
 - Dan Simmons
 | 
			
		||||
 - demmm
 | 
			
		||||
 - Emmanuel Arias
 | 
			
		||||
 - Enrique Medina Gremaldos
 | 
			
		||||
 - Erik Dubois
 | 
			
		||||
 - Dominic Hayes
 | 
			
		||||
 - El-Wumbus
 | 
			
		||||
 - Evan James
 | 
			
		||||
 - Frede H
 | 
			
		||||
 - Gabriel Craciunescu
 | 
			
		||||
 - Harald Sitter
 | 
			
		||||
 - Huang Jia Wen
 | 
			
		||||
 - Jerrod Frost
 | 
			
		||||
 - Jia Chao
 | 
			
		||||
 - Joe Kamprad
 | 
			
		||||
 - Jonas Strassel
 | 
			
		||||
 - Kai Dohmen
 | 
			
		||||
 - Kevin Kofler
 | 
			
		||||
 - Kyle Robertze
 | 
			
		||||
 - Lisa Vitolo
 | 
			
		||||
 - Matti Hyttinen
 | 
			
		||||
 - n3rdopolis
 | 
			
		||||
 - Neal Gompa
 | 
			
		||||
 - Nico 'dr460nf1r3'
 | 
			
		||||
 - Omer I.S.
 | 
			
		||||
 - Philip Müller
 | 
			
		||||
 - Ramon Buldó
 | 
			
		||||
 - Raul Rodrigo Segura
 | 
			
		||||
 - Rohan Garg
 | 
			
		||||
 - Santosh Mahto
 | 
			
		||||
 - Scott Harvey
 | 
			
		||||
 - Simon Quigley
 | 
			
		||||
 - Taejun Park
 | 
			
		||||
 - Victor Fuentes
 | 
			
		||||
 - vtriolet
 | 
			
		||||
 - Walter Lapchynski
 | 
			
		||||
 - Waneon Kim
 | 
			
		||||
 | 
			
		||||
 > This list was updated to revision 6e8d820737dea0f3e08f12b10768facef19be684 on May 28th 2022.
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,844 @@ contributors are listed. Note that Calamares does not have a historical
 | 
			
		||||
changelog -- this log starts with version 3.2.0. The release notes on the
 | 
			
		||||
website will have to do for older versions.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Calamares version 3.2.61 is the last one to have updated CHANGES-3.2
 | 
			
		||||
in the *calamares* (e.g. development, or 3.3, branch). For changes
 | 
			
		||||
in the stable release branch, see CHANGES-3.2 in that branch.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.61 (2022-08-24) #
 | 
			
		||||
 | 
			
		||||
This is the second community-maintainence release of Calamares 3.2.
 | 
			
		||||
It corrects a handful of bugs foud in the stable release. There
 | 
			
		||||
are also translation updates.
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Adriaan de Groot
 | 
			
		||||
 - Anke Boersma
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - The "About" and "Debug" buttons in a QWidgets-based panel were no
 | 
			
		||||
   longer translated. This has been fixed (by re-using translations
 | 
			
		||||
   of the same buttons from the QML module. #2030 (Thanks Anke)
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - *bootloader* Python code slipped in that was incompatible with
 | 
			
		||||
   the minimum required Python version. #2033 (Thanks Adriaan)
 | 
			
		||||
 - *locale* fixes a large regression introduced with 3.2.60, where
 | 
			
		||||
   the location picked for many locales was not the same as in 3.2.59,
 | 
			
		||||
   and generally peculiar (e.g. picking "English" led to "en_AG" which
 | 
			
		||||
   is nice if you are in Bermuda, but not expected in the rest of the
 | 
			
		||||
   world). #2008
 | 
			
		||||
 - *luksopenswaphookcfg* Remove duplicate options. #1659 (Thanks Anke)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.60 (2022-06-19) #
 | 
			
		||||
 | 
			
		||||
This is the first community-maintainence release of Calamares 3.2.
 | 
			
		||||
Somewhat ironically, all the commits in the branch come from
 | 
			
		||||
Adriaan de Groot -- the community is working in the 3.3 (*calamares*)
 | 
			
		||||
branch.
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - No core changes
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - *fstab* now warns when the mount options are empty (which is non-
 | 
			
		||||
   sensical, and indicates that the configuration is bad).
 | 
			
		||||
 - *locale* does a better job of preserving Catalan (Valencia)
 | 
			
		||||
   across modules; previously it dropped the *Valencia*
 | 
			
		||||
   after the locale module unless you specifically re-selected
 | 
			
		||||
   `ca@valencia` in the locale module. (Reported by Lliurex)
 | 
			
		||||
 - *welcome* now has text labels on the special buttons (nominally,
 | 
			
		||||
   this is part of the core, but the *About* button was always on the
 | 
			
		||||
   welcome page).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.59 (2022-05-29) #
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Arjen Balfoort
 | 
			
		||||
 | 
			
		||||
This is the final release of Calamares 3.2 where the release is from
 | 
			
		||||
the *calamares* branch -- that is, where the primary development
 | 
			
		||||
branch is also the branch being released regularly. Future releases
 | 
			
		||||
of the 3.2 series are bugfix-only, and no new feature development
 | 
			
		||||
or translations are expected. This is also the final release done
 | 
			
		||||
*as work-work* by the current maintainer.
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - Prep-work for moving the *About Calamares* button to the panels,
 | 
			
		||||
   rather than keeping it in the Welcome module. The about information
 | 
			
		||||
   is somewhat more flexible now, so that a new maintainer can be added
 | 
			
		||||
   easily without frustrating translators.
 | 
			
		||||
 - The progress panels (both Widgets and QML) now have an About button
 | 
			
		||||
   on them, showing the traditional *About Calamares* dialog.
 | 
			
		||||
 - Translations for the (QML) slideshow were not being loaded correctly.
 | 
			
		||||
   The log is now somewhat more informative when that fails.
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - *fstab* can now be configured to put `/tmp` on a *tmpfs*, and this can
 | 
			
		||||
   depend on it being on an SSD or not. Options applicable to `/tmp` can
 | 
			
		||||
   be configured separately as well. #1818 (Thanks Arjen)
 | 
			
		||||
 - *partition* now has some support for re-using LUKS partitions.
 | 
			
		||||
   (Thanks Arjen)
 | 
			
		||||
 - *partition* will cycle out a LUKS key if all the key slots are in use
 | 
			
		||||
   and a new key is added, rather than crashing the installer. (Thanks Arjen)
 | 
			
		||||
 - *welcome* and *welcomeq* have no *About* button anymore; this is now
 | 
			
		||||
   available from the progress panel, since it's also not-really about the
 | 
			
		||||
   distro itself.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.58.2 (2022-05-24)
 | 
			
		||||
 | 
			
		||||
This is a extra-quick release for an issue that shows up when using a
 | 
			
		||||
swap **file** on a btrfs filesystem; the installation would fail with
 | 
			
		||||
a Python error, raised from btrfs-progs. Reported by Evan James, Erik
 | 
			
		||||
Dubois, TechXero.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.58.1 (2022-05-20)
 | 
			
		||||
 | 
			
		||||
This is a hot-fix release for a regression in the *partition* module where
 | 
			
		||||
it was impossible to proceed unless *Encrypt system* was checked.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.58 (2022-05-18) #
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Anke Boersma
 | 
			
		||||
 - Arjen Balfoort
 | 
			
		||||
 - Enrique Medina Gremaldos
 | 
			
		||||
 - Evan James
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - Internal improvements to translations-setup means that Catalan (in the
 | 
			
		||||
   Valencian dialect), Occitan (Lenga d'Oc) and Serbian (in Latin script)
 | 
			
		||||
   are all better supported. Thanks Enrique.
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - *netinstall* Now displays entries with an empty name slightly differently.
 | 
			
		||||
   An empty name is not generally useful, but in combination with
 | 
			
		||||
   *immutable:true* and *selected:false* can be used to introduce separators
 | 
			
		||||
   or descriptive comments into the list of packages.
 | 
			
		||||
 - *partition* does not offer full-disk encryption when using ZFS. ZFS and the
 | 
			
		||||
   way Calamares sets up FDE don't mix well. (Thanks Evan)
 | 
			
		||||
 - *partition* Various bugs related to LUKS have been fixed. (Thanks Arjen)
 | 
			
		||||
 - *users* module now has a structured *user* key with settings specific
 | 
			
		||||
   to the user (shell, in particular). This maintains backwards compatibility
 | 
			
		||||
   with the *userShell* key.
 | 
			
		||||
 - *users* module now has lists of forbidden login- and host-names, to
 | 
			
		||||
   avoid settings that will mess up the install (e.g. using a login-name
 | 
			
		||||
   that is one of the system's reserved names). #1944
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.57 (2022-05-04) #
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Arjen Balfoort (new contributor! Welcome!)
 | 
			
		||||
 - Victor Fuentes
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - Calamares can now be started in Serbian (Latin Script) and Catalan
 | 
			
		||||
   (Valencia) when the LANG environment variable is set to values
 | 
			
		||||
   that indicate those languages.
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - *fstab* and *luksbootkeyfile* have better support for an **un**encrypted
 | 
			
		||||
   `/boot` partition. #1931 (thanks Arjen)
 | 
			
		||||
 - *packagechooser* and *packagechooserq* can now be given a custom name
 | 
			
		||||
   in the side-panel. #1932 (thanks Victor)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.56 (2022-04-22) #
 | 
			
		||||
 | 
			
		||||
As of this release, Calamares 3.2 development is winding down. The
 | 
			
		||||
reason is simple: systems where the backwards-compatibility of Calamares
 | 
			
		||||
3.2 is important are becoming increasingly difficult to work with
 | 
			
		||||
for **other** reasons. Foremost among these are deprecated versions
 | 
			
		||||
of dependencies and tools. Calamares 3.2 branch remains open for
 | 
			
		||||
bugfixes and will see a few more releases, but development is now
 | 
			
		||||
shifting wholesale to the newer generation.
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Victor Fuentes (new contributor! Welcome!)
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - Changes in git forced some changes on the CI tooling.
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - *locale* showed the wrong timezone for Dhaka, although it configured
 | 
			
		||||
   the correct one. #1929
 | 
			
		||||
 - *users* module sets global storage key *fullname* to the full name
 | 
			
		||||
   of the user (e.g. what is entered in the "your full name" box on the
 | 
			
		||||
   users page). #1923 (Thanks Victor)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.55 (2022-04-11) #
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - vtriolet (new contributor! Welcome!)
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - `readTargetFile()` did not properly return all the lines of the target
 | 
			
		||||
   file. #1918 (thanks vtriolet)
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - *users* module has rearranged configuration for setting the hostname.
 | 
			
		||||
   Legacy settings are preserved, but produce a warning. Please see
 | 
			
		||||
   `users.conf` for details.
 | 
			
		||||
 - *users* module has a new hostname.location setting, *Transient*, which
 | 
			
		||||
   will force the installed system to transient-hostname-setting by removing
 | 
			
		||||
   the file `/etc/hostname`.
 | 
			
		||||
 - *users* module has a new hostname.template setting, which allows some
 | 
			
		||||
   tweaking of how the hostname suggestion is constructed. In particular,
 | 
			
		||||
   it can be configured to use the current hostname (whatever that may be).
 | 
			
		||||
   See the example `users.conf` for details on available keys.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.54 (2022-03-21) #
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically):
 | 
			
		||||
 - Bob van der Linden (new contributor! Welcome!)
 | 
			
		||||
 - El-Wumbus (new contributor! Welcome!)
 | 
			
		||||
 - Evan James
 | 
			
		||||
 - Santosh Mahto (new contributor! Welcome!)
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - During the installation ("exec") step, while the slideshow is displayed,
 | 
			
		||||
   there is also a button to show the scrolling installation log as it
 | 
			
		||||
   is written. (Thanks Bob)
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - *fstab* module correctly handles empty UUID strings. (Thanks Evan)
 | 
			
		||||
 - *partition* module no longer forgets configured partition-layouts.
 | 
			
		||||
   It also respects configured partition labels better. (Thanks Santosh)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.53 (2022-03-04) #
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Huang Jia Wen (new contributor! Welcome!)
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - Automount-manipulation (to switch off KDE Plasma automounting new devices)
 | 
			
		||||
   now logs slightly more as it works. Defaults have changed in KDE Plasma
 | 
			
		||||
   5.24 and it turns out the automount-manipulation does not work well.
 | 
			
		||||
   Distro's are encouraged to turn off automount in the live ISO (see #1885).
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - *bootloader* now knows about loongarch64 and can install suitable EFI
 | 
			
		||||
   files for this CPU type. (Thanks Huang Jia Wen)
 | 
			
		||||
 - Progress reporting for `pacman` from the *packages* module has been switched
 | 
			
		||||
   off. The progress reporting works under low load, but there are many reports
 | 
			
		||||
   of it crashing (from XeroLinux and from Evan James, who has been debugging
 | 
			
		||||
   the issue) during a regular installation with thousands of updates. This
 | 
			
		||||
   will be revisited in the next release.
 | 
			
		||||
 - The *umount* module was buggy and did not actually unmount anything.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.52 (2022-02-25) #
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Evan James
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - No core changes yet
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - *fstab* recognizes nvme and mmc devices correctly as SSDs now. #1883
 | 
			
		||||
 - *luksbootkeyfile* handles trailing slashes in mount point
 | 
			
		||||
 - *partition* can be built with a new `SKIP` option, which skips
 | 
			
		||||
   the actual formatting steps but does not fail. The old `LAME`
 | 
			
		||||
   option is renamed `BAIL_OUT`.
 | 
			
		||||
 - *users* has a new key *sudoersConfigureWithGroup* to allow for
 | 
			
		||||
   different styles of sudo configuration. #1887
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.51 (2022-02-01) #
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Evan James
 | 
			
		||||
 | 
			
		||||
**WARNING** The *umount* module has been rewritten in C++. Check your
 | 
			
		||||
configuration if you previously used the copy-a-log functionality.
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - Evan has made a start on documenting which Global Storage keys there
 | 
			
		||||
   are and how they tie modules together. This can be found in the
 | 
			
		||||
   `src/modules/README.md` documentation.
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - *bootloader* can now be configured to try to generate a unique
 | 
			
		||||
   suffix for the bootloader-id. #1820
 | 
			
		||||
 - *grubcfg* now has a configurable default for kernel parameters,
 | 
			
		||||
   which allows distributions to change the value from `quiet`.
 | 
			
		||||
   The default, if nothing is set, remains `quiet`. Use an explicitly-
 | 
			
		||||
   empty list to specify no-arguments-at-all.
 | 
			
		||||
 - *packagechooser* can now export its choices for use by the *netinstall*
 | 
			
		||||
   module. This makes it possible to use *packagechooser* for large-scale
 | 
			
		||||
   choices, followed by *netinstall* for fine-grained control. (Thanks Evan)
 | 
			
		||||
 - When the *partition* module has a conflicting configuration for the
 | 
			
		||||
   swap choices, it prints a warning and uses the configured choice, rather
 | 
			
		||||
   than always using "suspend". #1881
 | 
			
		||||
 - The *umount* module has been re-written in C++. The copy-a-log-file
 | 
			
		||||
   functionality has been removed. Use the *preservefiles* module for that.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.50 (2022-01-18) #
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Anke Boersma
 | 
			
		||||
 - Erik Dubois
 | 
			
		||||
 - Evan James
 | 
			
		||||
 - Johannes Kamprad
 | 
			
		||||
 - Taejun Park (new contributor, welcome!)
 | 
			
		||||
 | 
			
		||||
**Replacement notice:** The *umount* module will be replaced by a C++
 | 
			
		||||
implementation in the next release. The "preserve log file" feature
 | 
			
		||||
will be removed in that release. Use the *preservefiles* module instead.
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - No core changes yet
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - *initcpiocfg* mentioned a special kernel-name "all", which did not work,
 | 
			
		||||
   and a special kernel-name "$uname" which cannot work. Fixed the former
 | 
			
		||||
   and removed the "$uname" special key. (Thanks Evan)
 | 
			
		||||
 - *luksswaphookcfg* has been converted to a C++ module.
 | 
			
		||||
 - *networkcfg* could fail to update the NetworkManager configuration
 | 
			
		||||
   if the SSID or username contained non-ASCII characters **and** the
 | 
			
		||||
   default Python text-file encoding was set to ASCII. The files are
 | 
			
		||||
   now read and written in UTF-8, explicitly. #1848
 | 
			
		||||
 - *partition* always sets *bigtime* option on XFS filesystems, if possible.
 | 
			
		||||
   Requires sufficiently-recent xfsprogs. #1874
 | 
			
		||||
 - *preservefiles* was missing some necessary features, needed for it
 | 
			
		||||
   to replace the deprecated log-file-saving functionality in the *umount*
 | 
			
		||||
   module. (Thanks Erik and Joe for testing) #1851
 | 
			
		||||
 - *umount* is now marked as an emergency module in the example configuration,
 | 
			
		||||
   since it should **probably** be run as a cleanup. (Thanks Evan)
 | 
			
		||||
 - *welcome* and *locale* could be confusing, together, and configure
 | 
			
		||||
   the target system with a language that does not match the installer
 | 
			
		||||
   language, even though the user did not make any explicit choice.
 | 
			
		||||
   (Thanks Taejun) #1864
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.49.1 (2021-12-11) #
 | 
			
		||||
 | 
			
		||||
This is a hot-fix release, to fix a regression in the calculation of
 | 
			
		||||
swap-size. Reported by EndeavourOS (Joe Kamprad) and Xero Linux.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.49 (2021-12-10) #
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Artem Grinev
 | 
			
		||||
 - Evan James
 | 
			
		||||
 | 
			
		||||
Distributions are **specifically** reminded to update the *umount* module
 | 
			
		||||
configuration (and to use *preservefiles* if needed).
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - Errors (e.g. when an installation fails for whatever reason) are displayed
 | 
			
		||||
   in a dialog with a scrollable details panel, rather than growing up
 | 
			
		||||
   to the size of the screen. (Thanks Artem)
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - *bootloader* better supports multiple installations of the same OS.
 | 
			
		||||
 - *mount* supports btrfs subvolumes on subdirectories of / now.
 | 
			
		||||
 - *partition* now supports "deep" btrfs subvolume names, e.g. a
 | 
			
		||||
   separate subvolume for `/usr/local`. (Thanks Evan)
 | 
			
		||||
 - The *umount* module now warns if the "preserve log file" feature is used.
 | 
			
		||||
   This has been deprecated for a long time: use the *preservefiles* module
 | 
			
		||||
   instead. A future release will turn this into an error.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.48 (2021-12-03) #
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Evan James
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - Python modules now have `warn()` and `error()` methods they can call,
 | 
			
		||||
   alongside the existing `debug()` and `warning()` (all live in the
 | 
			
		||||
   *libcalamares.utils* module).
 | 
			
		||||
 - Python modules can load YAML files via `libcalamares.utils.load_yaml()`.
 | 
			
		||||
   This may be the most useful for test-scripts.
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - *fstab* now has a separate, special, flags-setting for swap subvolumes
 | 
			
		||||
   on btrfs. A swap subvolume is created if a swap **file** (not a separate
 | 
			
		||||
   partition) is selected in the auto-partitioning page. (Thanks Evan)
 | 
			
		||||
 - When using btrfs, the *mount* module creates subvolumes. It was not
 | 
			
		||||
   possible to **avoid** having a subvolume name created for the root.
 | 
			
		||||
   This is now possible. #1837
 | 
			
		||||
 - The *packages* module now has some special settings for the `pacman`
 | 
			
		||||
   package manager (generally used on Arch-derivatives). This allows
 | 
			
		||||
   tweaking of the installation process, if downloads are slow or
 | 
			
		||||
   packages may fail to install. See the `packages.conf` file for
 | 
			
		||||
   details. (Thanks Evan)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.47 (2021-11-19) #
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Evan James
 | 
			
		||||
 - Jonas Strassel
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - The translation for Sinhala (`si`) has reached 100%. Thank you to
 | 
			
		||||
   හෙළබස and Sandaruwan, translators for Sinhala, for special effort
 | 
			
		||||
   in completing that translation.
 | 
			
		||||
 - Logging now supports Redacted names. This reduces the scope for
 | 
			
		||||
   leaking names or other private information through the logs
 | 
			
		||||
   (if they are posted to a pastebin). A name is redacted consistently
 | 
			
		||||
   within one run of Calamares, but differently each time.
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - *bootloader* with systemd-boot now handles root subvolumes better
 | 
			
		||||
   (Thanks Evan)
 | 
			
		||||
 - *displaymanager* supports the *greetd* display manager, which is a
 | 
			
		||||
   kind of meta-DM itself, supporting multiple greeters. (Thanks Jonas)
 | 
			
		||||
 - *finishedq* now has an extra example QML file that builds the UI in
 | 
			
		||||
   a different fashion, demonstrating how a mobile-OS customization of
 | 
			
		||||
   Calamares would present the "all done" message.
 | 
			
		||||
 - *fstab* has an example configuration file that mentioned `space_cache`
 | 
			
		||||
   as an option. Since 2014 there was only one possible value, so this
 | 
			
		||||
   option matched the default-and-only value. Newer kernels with newer
 | 
			
		||||
   btrfs versions have a `v2` option value as well. Remove the example
 | 
			
		||||
   option, since the kernel automatically picks the right value, while
 | 
			
		||||
   setting it to the wrong one may prevent the system from booting.
 | 
			
		||||
   (Thanks Evan)
 | 
			
		||||
 - The *partition* module no longer logs recognizable disk names or
 | 
			
		||||
   UUIDs. These are redacted in the logs. #1593
 | 
			
		||||
 - The *partition* module, together with the new *zfs* module and changes
 | 
			
		||||
   in *mount* and *bootloader* can install to ZFS **if** the distribution
 | 
			
		||||
   kernel supports it. ZFS tools are required, as well as the relevant
 | 
			
		||||
   kernel modules. See the `README.md` in the *zfs* module. (Thanks Evan)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.46 (2021-11-09) #
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Philip Müller
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - A new core class `Runner` is now responsible for running commands
 | 
			
		||||
   either in the host or in the target system. This is invisible for
 | 
			
		||||
   end-users, but **does** expand the API available to consumers inside
 | 
			
		||||
   Calamares modules. In particular, Python modules can now easily read
 | 
			
		||||
   and respond to command output. #1740
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - *fstab* writes a slightly different message in `/etc/crypttab`
 | 
			
		||||
   about the root filesystem. Since Calamares itself ignores the
 | 
			
		||||
   (previous wording of) message, it was confusing. #1811
 | 
			
		||||
 - *packages* module has some support for reporting progress while
 | 
			
		||||
   the packages are installed. This depends on the package-manager itself
 | 
			
		||||
   reporting useful progress information **and** the *packages* module having
 | 
			
		||||
   support-code to interpret that progress. A proof-of-concept for `pacman`
 | 
			
		||||
   has been implemented. #1582
 | 
			
		||||
 - *partition* has a number of edge-cases for LVM and LUKS resolved. #1564 #1817
 | 
			
		||||
 - *partition* module once again always offers `/boot` as a mount-point, even
 | 
			
		||||
   when EFI would want `/boot/efi`. (Thanks Phil)
 | 
			
		||||
 - *summary* had a regression and showed some descriptive texts twice.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.45 (2021-10-31) #
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Evan James (new contributor, welcome!)
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - New internal convenience functions from Evan
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - *packagechooser* now displays screenshots nicely-scaled
 | 
			
		||||
   rather than jagged. (#1807)
 | 
			
		||||
 - *partition* module removes ZFS partitions directly. At install-time,
 | 
			
		||||
   we think that the partitions should be handled separately from a
 | 
			
		||||
   zpool that potentially includes those partitions. (Thanks Evan)
 | 
			
		||||
 - *services-systemd* supports timers, e.g. for weekly trim on SSDs.
 | 
			
		||||
   (Thanks Evan)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.44.3 (2021-10-04) #
 | 
			
		||||
 | 
			
		||||
This is not a hotfix release, but a tiny-tiny incremental improvement
 | 
			
		||||
that fixes one hugely annoying -- user-facing message presenting
 | 
			
		||||
bytes as mebibytes -- bug in the partition module.
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - The *partition* module now consistently uses the configured EFI
 | 
			
		||||
   partition size (defaults to 300MiB).
 | 
			
		||||
 - Internal changes in the *summary* module to increase consistency
 | 
			
		||||
   between *summary* and *summaryq*.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.44.2 (2021-09-27) #
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Corey Lang (new contributor, welcome!)
 | 
			
		||||
 | 
			
		||||
This is a hotfix for a typo -- not a syntax error -- that affects the
 | 
			
		||||
*networkcfg* module. Reported and fixed by Corey.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.44.1 (2021-09-24) #
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Anke Boersma
 | 
			
		||||
 | 
			
		||||
This is a hotfix for a typo -- not a syntax error -- that affects the
 | 
			
		||||
*initcpiocfg* module. Reported and fixed by Anke.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.44 (2021-09-24) #
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Anke Boersma
 | 
			
		||||
 - Shrinivas Vishnu Kumbhar (new contributor, welcome!)
 | 
			
		||||
 - whorfin (new contributor, welcome!)
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - "Log spam" has been reduced a little in the partitioning module.
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - *initcpiocfg* has had a number of internal code-fixes, and now adds
 | 
			
		||||
   the `consolefont` hook by default as well. (Thanks Shrinivas)
 | 
			
		||||
 - Both *locale* and *keyboard* have received some tweaks for configurations
 | 
			
		||||
   in India; unless the user selects otherwise, English is preferred.
 | 
			
		||||
 - The *luksbootkeyfile* module was reported to be too quick to declare
 | 
			
		||||
   a timeout when applying the keyfile. The timeout has been increased
 | 
			
		||||
   to one minute. (Thanks whorfin)
 | 
			
		||||
 - *networkcfg* tries harder to find the live-user login for re-working
 | 
			
		||||
   networking settings. This fixes a regression on FerenOS, where the
 | 
			
		||||
   installer was crashing because it could not find the live-user login.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.43 (2021-09-17) #
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Anke Boersma
 | 
			
		||||
 - Joe Kamprad
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - Translations have been made more consistent. In particular, some *OK*,
 | 
			
		||||
   *Yes*, *No* and *Cancel* buttons that were previously untranslated
 | 
			
		||||
   or "stuck" in the language that Calamares started in, are now
 | 
			
		||||
   changed to the current language as selected in the welcome page.
 | 
			
		||||
 - Documentation improvements from Joe Kamprad. A *sizeLimit* of zero
 | 
			
		||||
   (which is the default if nothing is set in the branding configuration)
 | 
			
		||||
   disables log uploads.
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - The *keyboardq* module (QML-based UI for keyboard-layout-selection)
 | 
			
		||||
   now features an interactive keyboard preview and has the
 | 
			
		||||
   layout adjusted. (Thanks Anke)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.42 (2021-09-06) #
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Anke Boersma
 | 
			
		||||
 - Artem Grinev
 | 
			
		||||
 - Nico 'dr460nf1r3' (new contributor, welcome!)
 | 
			
		||||
 - Waneon Kim (new contributor, welcome!)
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - No core changes yet
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - BTRFS partitions are no longer listed as "check in phase 2" in
 | 
			
		||||
   the *fstab* module. (Thanks Nico)
 | 
			
		||||
 - The *keyboard* module (and *keyboardq*) now pick an English layout
 | 
			
		||||
   (with Rupee) for keyboards when the language is English and locale is India,
 | 
			
		||||
   rather than Hindi layout.
 | 
			
		||||
 - The *localeq* module had the i18n.qml rewritten to make it easier
 | 
			
		||||
   to customize. A bug in the layout has been fixed, and the overall
 | 
			
		||||
   look has been updated.
 | 
			
		||||
 - *networkcfg* now translates the "live user" on an ISO to the regular
 | 
			
		||||
   user on the installed system, so that network configuration changes
 | 
			
		||||
   made in the live system are automatically used after installation. #1755
 | 
			
		||||
 - *partition* no longer allows you to delete an extended partition with
 | 
			
		||||
   children (which led to crashes). #1749 (Thanks Artem)
 | 
			
		||||
 - *partition* complains in more detail about the state of the UEFI
 | 
			
		||||
   boot partition (under manual partitioning schemes). #1761
 | 
			
		||||
 - *welcome* can now check multiple URLs to determine if internet connectivity
 | 
			
		||||
   is available. It is still recommended to check the distro home-page or
 | 
			
		||||
   some special "ping" page of the distro, although that has some privacy
 | 
			
		||||
   implications; using example.com or google.com may work as well. Listing
 | 
			
		||||
   multiple URLs will ping each of them in turn until one succeeds. #1669
 | 
			
		||||
 - The work to make a QML version available for all view modules is almost
 | 
			
		||||
   completed. Two new QML modules have been added *packagechooserq* and *summaryq*.
 | 
			
		||||
   Summaryq brings the option to present the summary page in a customizable
 | 
			
		||||
   way, with a bit more of a contemporary look. Packagechooserq adds the option
 | 
			
		||||
   to preselect an item and displays all options in one overview.
 | 
			
		||||
   (Thanks Anke)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.41.1 (2021-08-05) #
 | 
			
		||||
 | 
			
		||||
This is a hotfix release for a crash in the *partition* module, reported on
 | 
			
		||||
KDE neon. #1746
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.41 (2021-07-31) #
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Anke Boersma
 | 
			
		||||
 - Camilo Higuita
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - The (re)translation framework has been internally re-vamped to be
 | 
			
		||||
   less resource-intensive and to work with all QObjects, not just
 | 
			
		||||
   widgets. Consumers of the translations framework are expected to
 | 
			
		||||
   set up the event filter on the top-level widget(s) manually. Since
 | 
			
		||||
   Calamares and the Calamares-test-applications have been adjusted already,
 | 
			
		||||
   no further action is needed.
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - When the *keyboard* module is activated, it no longer replaces
 | 
			
		||||
   an explicit user choice (e.g. for a Belgian layout) by a guessed-for-
 | 
			
		||||
   this-language layout (e.g. Danish if you're installing in Danish).
 | 
			
		||||
 - Logic for handling installation lists has been moved around in the
 | 
			
		||||
   *packages* module so that package managers can, in principle,
 | 
			
		||||
   adjust how to handle critical and non-critical package lists.
 | 
			
		||||
 - In the *partition* module, translation code has been simplified.
 | 
			
		||||
 - The *usersq* module has had a fair bit of QML rewritten to make it easier
 | 
			
		||||
   to customize the colors used by the module in a consistent way.
 | 
			
		||||
   (Thanks Anke)
 | 
			
		||||
 - *Welcome* now uses a translated message from the Config object,
 | 
			
		||||
   increasing the sharing between widgets- and QML-modules.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.40 (2021-07-14) #
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Anke Boersma
 | 
			
		||||
 - Anubhav Choudhary (SoK success!)
 | 
			
		||||
 - Emmanuel Arias (new contributor! welcome!)
 | 
			
		||||
 - Erik Dubois
 | 
			
		||||
 - Jerrod Frost (new contributor! welcome!)
 | 
			
		||||
 - Jia Chao (new contributor! welcome!)
 | 
			
		||||
 - Joe Kamprad
 | 
			
		||||
 - Lisa Vitolo (blast from the past!)
 | 
			
		||||
 - Omer I.S. (new contributor! welcome!)
 | 
			
		||||
 | 
			
		||||
In project news, chat (instant-messaging) communications has largely
 | 
			
		||||
moved to Matrix and Libera.Chat. CI notifications -- issues and build
 | 
			
		||||
results -- are sent to Matrix only.
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - The CMake modules for consumption by external modules (e.g. the
 | 
			
		||||
   calamares-extensions repository, but also any other modules built
 | 
			
		||||
   by distro's for internal use) now support consistent skip-module
 | 
			
		||||
   behavior and reporting. #1641 (one tiny part of this change)
 | 
			
		||||
 - In global storage, the *filesystem_use* key now has an API in
 | 
			
		||||
   libcalamares to systematically mark filesystem (types) as "in use"
 | 
			
		||||
   or not. This, in turn, means that modules can depend on that information
 | 
			
		||||
   for other work (e.g. removing drivers for unused filesystems). #1635
 | 
			
		||||
 - The "upload log file" now has a configurable log-file-size. (Thanks Anubhav)
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - *bootloader* can now install an aarch64 (ARM) compatible EFI GRUB. (Thanks Jia)
 | 
			
		||||
 - *displaymanager* example configuration has been shuffled around a bit,
 | 
			
		||||
   for better results when the live image is running XFCE. Also lists
 | 
			
		||||
   more potential display managers. #1205 (Thanks Erik)
 | 
			
		||||
 - *keyboard* now switches on an alternate `en_US` keyboard layout when
 | 
			
		||||
   Arabic or Hebrew is selected as primary layout. (Thanks Omer)
 | 
			
		||||
 - *localeq* now has a fully functional offline option (alongside the default
 | 
			
		||||
   interactive map option, which requires internet).
 | 
			
		||||
 - The *netinstall* module can now fall back to alternative URLs when
 | 
			
		||||
   loading groups data. The first URL to yield a non-empty groups
 | 
			
		||||
   collection is accepted. No changes are needed in the configuration. #1673
 | 
			
		||||
 - *packagechooser* can now integrate with the *packages* module; that
 | 
			
		||||
   means you can specify package names to install for a given selection,
 | 
			
		||||
   and the regular package-installation mechanism will take care of it.
 | 
			
		||||
   Legacy configurations that use *contextualprocess* are still supported.
 | 
			
		||||
   See the `packagechooser.conf` file for details. #1550
 | 
			
		||||
 - A long-neglected pull request from Lisa Vitolo for the *partition*
 | 
			
		||||
   module -- allowing to set filesystem labels during manual partitioning --
 | 
			
		||||
   has been revived and merged.
 | 
			
		||||
 - The *partition* manager has had a long-standing bug with partition-flags
 | 
			
		||||
   and manual partitioning resolved. This may help resolve some installation
 | 
			
		||||
   issues on UEFI systems. #1724
 | 
			
		||||
 - *usersq* is further implemented and can now be used for a successful install.
 | 
			
		||||
   Not all warning messages available in the regular users module are implemented.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.39.3 (2021-04-14) #
 | 
			
		||||
 | 
			
		||||
A minor bugfix tweak release. Since this contains yet **another**
 | 
			
		||||
autologin-related fix, and there is nothing large enough to justify
 | 
			
		||||
a 3.2.40 release yet, add it to the growing tail of 3.2.39. (Reported
 | 
			
		||||
by Joe Kamprad, #1672). Also fixes a regression from 3.2.28 in
 | 
			
		||||
localized packages (e.g. *package-LOCALE* did not work).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.39.2 (2021-04-02) #
 | 
			
		||||
 | 
			
		||||
This is **another** hotfix release for issues around autologin ..
 | 
			
		||||
autoLogin, really, since the whole problem is that internal capitalization
 | 
			
		||||
changed. An unrelated bug in writing /etc/default/keyboard was
 | 
			
		||||
also fixed. (Reported by pcrepix, #1668)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.39.1 (2021-03-30) #
 | 
			
		||||
 | 
			
		||||
This hotfix release corrects a regression in the *displaymanager*
 | 
			
		||||
module caused by changes in the *users* module; autologin was
 | 
			
		||||
internally renamed and no longer recognized by the *displaymanager*
 | 
			
		||||
module. (Reported by Erik Dubois, #1665)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.39 (2021-03-19) #
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Matti Hyttinen
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - A *packages* service has been added to the core, for use by
 | 
			
		||||
   *netinstall* module and any others that need to set up
 | 
			
		||||
   package information for the *packages* module.
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - The *mount* module has gained a configurable setup for btrfs volumes.
 | 
			
		||||
   If your distro has a default-to-btrfs setup, it can skip the hard-
 | 
			
		||||
   coded setup (which Calamares has had for a long time with @home
 | 
			
		||||
   and similar) and introduce a custom btrfs configuration through the
 | 
			
		||||
   `mount.conf` file. See issues #1659 and #1661 for warnings about
 | 
			
		||||
   using this in production.
 | 
			
		||||
 - *netinstall* now supports fallbacks for the groups data.
 | 
			
		||||
   Instead of a single URL, multiple URLs may be specified in
 | 
			
		||||
   a list and Calamares goes through them until one is successfully
 | 
			
		||||
   retrieved. Older configurations with a single string are
 | 
			
		||||
   treated like a one-item list. #1579
 | 
			
		||||
 - The *usersq* module now connects to the internal configuration
 | 
			
		||||
   object and may be usable for regular installations.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.38.1 (2021-03-15) #
 | 
			
		||||
 | 
			
		||||
This hotfix release is for this item in the release notes of 3.2.38:
 | 
			
		||||
 - The .desktop file for Calamares now makes a longer trip, calling
 | 
			
		||||
   `sh -c "pkexec calamares"`; distributions may still need to adjust.
 | 
			
		||||
The change had been lost while updating other files. It has been restored
 | 
			
		||||
in `calamares.desktop` and `calamares.desktop.in`. (Reported by Erik)
 | 
			
		||||
Other minor changes and fixes:
 | 
			
		||||
 - presets in the *users* module show the hostname, too,
 | 
			
		||||
 - translations update for Korean, Ukranian and Chinese (zh_TW).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.38 (2021-03-14) #
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Anke Boersma
 | 
			
		||||
 - Anubhav Choudhary
 | 
			
		||||
 - Neal Gompa
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - Uploading your log files (in case of installation failure) has been
 | 
			
		||||
   expanded and is now more configurable. Users should still take care
 | 
			
		||||
   when uploading logs, and distro's should configure a URL with
 | 
			
		||||
   no public viewing of those logs. (Thanks Anubhav)
 | 
			
		||||
 - The .desktop file for Calamares now makes a longer trip, calling
 | 
			
		||||
   `sh -c "pkexec calamares"`; distributions may still need to adjust.
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - A new QML-based *finishedq* module has been added. (Thanks Anke)
 | 
			
		||||
 - The *packages* module no longer supports *urpmi*; no Calamares-
 | 
			
		||||
   consumers with that package manager seem to exist. (Thanks Neal)
 | 
			
		||||
 - The *users* module now can set a fixed username and prevent editing.
 | 
			
		||||
   The *presets* configuration entry in `users.conf` can set a *loginName*
 | 
			
		||||
   and a *fullName* and (independently) enable or disable editing of
 | 
			
		||||
   that value. You can, for instance, set *loginName* to "manjaro" if
 | 
			
		||||
   you like; the user can change it afterwards. You could set the
 | 
			
		||||
   *loginName* to "oem" and prevent editing it as well. #942
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.37 (2021-02-23) #
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - benne-dee
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - Calamares has a table of 'best guess' languages for each country
 | 
			
		||||
   and when GeoIP is enabled, it will automatically select that
 | 
			
		||||
   country's language as default -- the user can of course pick
 | 
			
		||||
   a different one. The 'best guess' is based on Unicode / ISO
 | 
			
		||||
   data, which is sometimes dubious. Based on some personal notes,
 | 
			
		||||
   the 'best guess' language for Belarus has been changed to Russian.
 | 
			
		||||
 - Calamares has a table of 'best guess' keyboard mappings,
 | 
			
		||||
   allowing native language input. However, usernames and
 | 
			
		||||
   passwords should be in US-ASCII (this is a limitation of
 | 
			
		||||
   the login system -- **some** parts of the system will support
 | 
			
		||||
   non-ASCII input, but it's better safe than sorry).
 | 
			
		||||
   Add Greek to the list of languages that needs US-ASCII
 | 
			
		||||
   in addition to native input.
 | 
			
		||||
 - The CI infrastructure now builds Calamares and Calamares-extensions
 | 
			
		||||
   on a nightly basis.
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - The *netinstall* module has a YAML schema, allowing packagers
 | 
			
		||||
   to validate and verify their netinstall configurations before
 | 
			
		||||
   shipping an ISO (or writing bug reports). Thanks benne-dee.
 | 
			
		||||
 - The *finished* module has been heavily refactored, opening
 | 
			
		||||
   the way to a QML-based version of the same module. This is
 | 
			
		||||
   also preparatory work for allowing packagers (e.g. PostmarketOS)
 | 
			
		||||
   to customize the messages on the finished page.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.36 (2021-02-03) #
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Anubhav Choudhary
 | 
			
		||||
 - benne-dee
 | 
			
		||||
 - Gaël PORTAY
 | 
			
		||||
 - Jonas Strassel
 | 
			
		||||
 - Kevin Kofler
 | 
			
		||||
 - Matti Hyttinen
 | 
			
		||||
 - Neal Gompa
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - It is now possible to hide the *next* and *back* buttons during
 | 
			
		||||
   the "exec" phase of installation. Thanks Anubhav.
 | 
			
		||||
 - The Calamares CI has migrated to GitHub actions. Thanks Jonas.
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - *bootloader* now uses the current file names for the UEFI Secure Boot
 | 
			
		||||
   shim instead of obsolete ones.
 | 
			
		||||
 - The *mount* module creates swap in its own subvolume, if btrfs is used.
 | 
			
		||||
   Thanks Matti.
 | 
			
		||||
 - *partition* includes more information about what it will do, including
 | 
			
		||||
   GPT partition types (in human-readable format, if possible). Thanks Gaël.
 | 
			
		||||
 - Some edge-cases with overlay filesystems have been resolved in the
 | 
			
		||||
   *partition* module. Thanks Gaël.
 | 
			
		||||
 - During the creation of filesystems and partitions, automounting is
 | 
			
		||||
   turned off (if DBus is available, and the host system supports
 | 
			
		||||
   KDE Solid automount control). This should reduce the number of
 | 
			
		||||
   failed installations if automount grabs partitions while they are
 | 
			
		||||
   being created. The code is prepared to handle other ways to control
 | 
			
		||||
   automount-behavior as well.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.35.1 (2020-12-07) #
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Anubhav Choudhary
 | 
			
		||||
 - Matti Hyttinen
 | 
			
		||||
 | 
			
		||||
Some strange string artifacts appeared, leading to `{1?}` being
 | 
			
		||||
displayed in various user-facing messages. These have been removed
 | 
			
		||||
and the translations updated.
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - The *initcpiocfg* module would sometimes configure the system to ask
 | 
			
		||||
   for a passphrase, when none is needed.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.2.35 (2020-11-30) #
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
							
								
								
									
										290
									
								
								CHANGES-3.3
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										290
									
								
								CHANGES-3.3
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,290 @@
 | 
			
		||||
<!-- SPDX-FileCopyrightText: no
 | 
			
		||||
     SPDX-License-Identifier: CC0-1.0
 | 
			
		||||
-->
 | 
			
		||||
 | 
			
		||||
This is the changelog for Calamares. For each release, the major changes and
 | 
			
		||||
contributors are listed. Note that Calamares does not have a historical
 | 
			
		||||
changelog -- this log starts with version 3.3.0. See CHANGES-3.2 for
 | 
			
		||||
the history of the 3.2 series (2018-05 - 2022-08).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.3.1 (unreleased)
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Nobody yet!
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - No changes of note.
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - No changes of note.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.3.0 (2023-12-12)
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Adriaan de Groot
 | 
			
		||||
 - Alberto Salvia Novella
 | 
			
		||||
 - Christophe Marin
 | 
			
		||||
 - Evan Maddock
 | 
			
		||||
 - Frede Hundewadt
 | 
			
		||||
 | 
			
		||||
Since this is the first non-alpha release of 3.3.0, we would like to thank
 | 
			
		||||
all the contributors to a year and a half of alpha releases, six in all.
 | 
			
		||||
Distributions are **strongly** advices to take the release notes of
 | 
			
		||||
the alpha's into account as well.
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - No changes of note.
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - *users* and *usersq* no longer support the password requirement 'nonempty'.
 | 
			
		||||
   Use 'minLength: 1' instead. The example configuration allows the user to
 | 
			
		||||
   choose any password at all, but also contains suggestions for other
 | 
			
		||||
   password-requirements schemes. (thanks Alberto)
 | 
			
		||||
 - *users* now can use stronger password hashes, if `crypt_gensalt()` is
 | 
			
		||||
   available in the *crypt* library. (thanks Evan)
 | 
			
		||||
 - *machineid* module supports several variations of writing /etc/machine-id .
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.3.0-alpha6 (2023-11-16)
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Adriaan de Groot
 | 
			
		||||
 - Anke Boersma
 | 
			
		||||
 | 
			
		||||
 This is a hotfix release because -alpha5 didn't compile,
 | 
			
		||||
 and Anke repaired the partition unit-tests when building with Qt6.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.3.0-alpha5 (2023-11-13)
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Adriaan de Groot
 | 
			
		||||
 - Alejo Fernandez
 | 
			
		||||
 - Anke Boersma
 | 
			
		||||
 - Christophe Marin
 | 
			
		||||
 - Emir Sari
 | 
			
		||||
 - Evan James
 | 
			
		||||
 - Gaël PORTAY
 | 
			
		||||
 - Gecko Linux
 | 
			
		||||
 - Jeremy Whiting
 | 
			
		||||
 - Neal Gompa
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - Boost::Python is no longer a dependency, Calamares uses a bundled copy
 | 
			
		||||
   of pybind11 instead. This speeds up compilation and reducese the
 | 
			
		||||
   dependency tree a great deal. You can set `WITH_PYBIND11=OFF` in the
 | 
			
		||||
   build to keep Boost::Python and all the binary-compatibility problems
 | 
			
		||||
   it entails.
 | 
			
		||||
 - Coding style now wants clang-format 15 or 16, but no longer needs astyle.
 | 
			
		||||
   There is also a clang-tidy file for additional styling support.
 | 
			
		||||
 - Ongoing translation improvements. (thanks Emir)
 | 
			
		||||
 - Translations for bqi (Luri), es_AR (Castellano), eo (Esperanto),
 | 
			
		||||
   ka (Georgian). In **non-release** builds (e.g. between releases,
 | 
			
		||||
   so for developers building directly from git) all translations are
 | 
			
		||||
   enabled, even the ones with no translations at all.
 | 
			
		||||
 - The logging format in the `session.log` file and on-screen is now
 | 
			
		||||
   more similar, although the file contains a lot more per-line information.
 | 
			
		||||
 - The INSTALL_CONFIG option has been restored. It is still a terrible
 | 
			
		||||
   idea to fork the repository to modify the config files, and you
 | 
			
		||||
   probably should have a calamares-config package with those files
 | 
			
		||||
   instead, there are packaging workflows that can usefully patch-and-
 | 
			
		||||
   install configuration files. The option defaults to OFF.
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - All QML modules now have a Qt6-compatible set of QML files as well. (thanks Anke)
 | 
			
		||||
 - *packagechooser* supports AppStream 1.0 API.
 | 
			
		||||
 - *unpackfs* now uses the `-S` option to rsync for sparse file support. (thanks Jeremy)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.3.0-alpha4 (2023-10-13)
 | 
			
		||||
 | 
			
		||||
Another closing-in-on-3.3.0 release! One of the big changes is that
 | 
			
		||||
Calamares -- the core and nearly all of the modules in this repository --
 | 
			
		||||
are compatible with Qt6. That is, it compiles. Functionality has not
 | 
			
		||||
been tested, but early-testing distributions are encouraged to submit
 | 
			
		||||
pull requests to improve the code.
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Adriaan de Groot
 | 
			
		||||
 - Anke Boersma
 | 
			
		||||
 - Emir Sari
 | 
			
		||||
 - Evan James
 | 
			
		||||
 - Hector Martin
 | 
			
		||||
 - Ivan Borzenkov
 | 
			
		||||
 - Simon Quigley
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - Qt6 compatibility. You can choose Qt5 (with KDE Frameworks 5) as before,
 | 
			
		||||
   or choose Qt6 (with KDE Frameworks 6). This means that a Qt6-based Linux
 | 
			
		||||
   distribution can use Calamares without needing an extra version of Qt.
 | 
			
		||||
   Note that some KDE Frameworks are required as well, and those need to be
 | 
			
		||||
   Qt6-based also (and are not released as of September 2023).
 | 
			
		||||
 - QML-based modules are also supported in Qt6, but the QML is likely to
 | 
			
		||||
   be source-incompatible. The *welcomeq* module shipped with Calamares
 | 
			
		||||
   now has two `.qrc` files and uses the `${QT_VERSION_SUFFIX}` variable
 | 
			
		||||
   to pick one of the two depending on the Qt version being used.
 | 
			
		||||
   Other modules are likely to follow the same pattern.
 | 
			
		||||
 - C++ namespaces have been shuffled around and `CalamaresUtils` has been
 | 
			
		||||
   retired. This has an effect on all C++ plugins, since this is neither
 | 
			
		||||
   a binary- nor source-compatible change.
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - *keyboard* module can now be explicitly configured to use X11 keyboard
 | 
			
		||||
   settings or the FreeDesktop locale1 DBus service. The latter is most
 | 
			
		||||
   useful for Calamares as an "initial setup" system, not an installer,
 | 
			
		||||
   in a Wayland session. (thanks Hector)
 | 
			
		||||
 - *keyboard* module now writes X11 layout configuration with variants
 | 
			
		||||
   for all non-ASCII (e.g. us) layouts. (thanks Ivan)
 | 
			
		||||
 - *keyboard* module now can configure keyboard switch. (thanks Ivan)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.3.0-alpha3 (2023-08-28)
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Adriaan de Groot
 | 
			
		||||
 - Aleksey Samoilov
 | 
			
		||||
 - Anke Boersma
 | 
			
		||||
 - Arjen Balfoort
 | 
			
		||||
 - Boria138
 | 
			
		||||
 - Brian Morison
 | 
			
		||||
 - Emir Sari
 | 
			
		||||
 - Evan Goode
 | 
			
		||||
 - Evan James
 | 
			
		||||
 - Ficelloo
 | 
			
		||||
 - Hector Martin
 | 
			
		||||
 - Jeremy Attall
 | 
			
		||||
 - Johannes Kamprad
 | 
			
		||||
 - Kasta Hashemi
 | 
			
		||||
 - Kevin Kofler
 | 
			
		||||
 - Mario Haustein
 | 
			
		||||
 - Masato TOYOSHIMA
 | 
			
		||||
 - Panda
 | 
			
		||||
 - Paolo Dongilli
 | 
			
		||||
 - Peter Jung
 | 
			
		||||
 - Philip Müller
 | 
			
		||||
 - Shivanand
 | 
			
		||||
 - Sławomir Lach
 | 
			
		||||
 - Sunderland93
 | 
			
		||||
 - wiz64
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - Incompatible module-configuration changes, see #1438.
 | 
			
		||||
 - Branding entries use ${var} instead of @{var} for substitutions,
 | 
			
		||||
   in line with all the other substitution mechanisms used from C++
 | 
			
		||||
   core. See documentation in `branding.desc`.
 | 
			
		||||
 - Boost::Python requires at least version 1.72.
 | 
			
		||||
 - KDE Frameworks must be version 5.58 or later.
 | 
			
		||||
 - The `INSTALL_CONFIG` option has been removed. If you are installing
 | 
			
		||||
   the example configuration files from the Calamares repository, just
 | 
			
		||||
   stop. That was never a good idea, and you should keep your configs elsewhere.
 | 
			
		||||
 - Progress percentage during install can now be localized. (thanks Emir)
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - *dracut* added a configurable kernel name. (thanks Anke)
 | 
			
		||||
 - *initcpiocfg* orders hookds slightly differently. (thanks Peter)
 | 
			
		||||
 - *localeq* moved to using Drawer instead of ComboBox in UI. (thanks Anke)
 | 
			
		||||
 - *keyboardq* moved to using Drawer instead of ComboBox in UI. (thanks Anke)
 | 
			
		||||
 - *netinstall* now has a new *noncheckable* option for groups, which prevent
 | 
			
		||||
   it a group from being checked/uncheckd as a whole. You can still check
 | 
			
		||||
   individual items **in** the group though. (thanks Shivanand)
 | 
			
		||||
 - *partition* can now pick LUKS or LUKS2. (thanks Jeremy)
 | 
			
		||||
 - *zfs* creates a hostid through zgenhostid.
 | 
			
		||||
 - *zfshostid* new module to copy zfs generated /etc/hostid
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.3.0-alpha2 (2022-08-23)
 | 
			
		||||
 | 
			
		||||
Second alpha release, with updated ABI compatibility checking,
 | 
			
		||||
some 3.3.0 release goals, new features in modules and important bugfixes.
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Adriaan de Groot
 | 
			
		||||
 - Anke Boersma
 | 
			
		||||
 - Evan James
 | 
			
		||||
 - Shivanand
 | 
			
		||||
 - Vitor Lopes
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 | 
			
		||||
A core **TODO** is moving all library code into the `Calamares` namespace,
 | 
			
		||||
dropping the `CalamaresUtils` namespace. Modern C++ supports nested namespaces,
 | 
			
		||||
so in some cases we can use those. This has a drastic effect on ABI compatibility,
 | 
			
		||||
though, as functions move from one namespace to another. This needs to be
 | 
			
		||||
completed before a 3.3.0 with ABI stability is released.
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 | 
			
		||||
Module schemas have been updated to reflect all the incompatible changes.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.3.0-alpha1 (2022-06-27)
 | 
			
		||||
 | 
			
		||||
Initial 3.3.0 alpha release to check the release scripts &c.
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Adriaan de Groot
 | 
			
		||||
 - Aleksey Samoilov
 | 
			
		||||
 - Anke Boersma
 | 
			
		||||
 - Dan Simmons
 | 
			
		||||
 - Evan James
 | 
			
		||||
 - Peter Jung
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 3.3.0-pre-alpha (unreleased) #
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Anke Boersma
 | 
			
		||||
 - Anubhav Choudhary
 | 
			
		||||
 - Evan James
 | 
			
		||||
 - Vitor Lopes
 | 
			
		||||
 | 
			
		||||
This is a "minor" version change, but the size of the changes is very
 | 
			
		||||
large. Configuration files from previous versions of Calamares will
 | 
			
		||||
**certainly** need to be re-validated. Take heed of the many changes
 | 
			
		||||
in the *Modules* heading, below.
 | 
			
		||||
 | 
			
		||||
Users (distributions) are **strongly** advised to use the tools
 | 
			
		||||
for configuration validation (`ci/configvalidator.py`) to check
 | 
			
		||||
that the distribution configuration files follow the current schema.
 | 
			
		||||
 | 
			
		||||
## Project ##
 | 
			
		||||
 - The C++ code in the project is now formatted with clang-format 12 or 13,
 | 
			
		||||
   with the coding-style as found in `.clang-format`; there are minor
 | 
			
		||||
   differences from the tool, compared to the clang-format 9 usually applied
 | 
			
		||||
   to Calamares 3.2.
 | 
			
		||||
 - The CMake code in the project is now formatted with gersemi 0.7.5.
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - CMake 3.16, Qt 5.15 are now required; the newer CMake is to support
 | 
			
		||||
   new features (also for KDE Frameworks), Qt is the current LTS version.
 | 
			
		||||
 - Running `calamares -d` no longer enforces a single-application
 | 
			
		||||
   (it is for debugging purposes, after all).
 | 
			
		||||
 - Python 3.6 or later is now required, to allow for F-strings in
 | 
			
		||||
   Python code and allow other tidy-ups in the Python modules.
 | 
			
		||||
   Boost::Python now requires 1.67 or later (for CMake support).
 | 
			
		||||
 - The log file now **always** contains a debug-log, and the `-D` flag
 | 
			
		||||
   primarily controls what is printed to stdout. By default, stdout
 | 
			
		||||
   only gets errors; use `-D6` to match stdout with the file. Use `-D8`
 | 
			
		||||
   to get an extra-verbose log file **and** verbose stdout.
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - *bootloader* now supports more options when building the kernel
 | 
			
		||||
   command-line. (Thanks Evan)
 | 
			
		||||
 - *bootloader* no longer supports `@@`-style suffixes for unique-EFI-id
 | 
			
		||||
   generation. Use `${}` instead.
 | 
			
		||||
 - *displaymanager* no longer supports the discontinued *kdm* display manager.
 | 
			
		||||
 - *fstab* configuration has been completely re-done. Many configuration
 | 
			
		||||
   options have moved to the *mount* module. See #1993
 | 
			
		||||
 - *grubcfg* changed the key *keepDistributor* to *keep_distributor*.
 | 
			
		||||
   Please update configurations.
 | 
			
		||||
 - *mount* now does most of the mounting; options that were in *fstab*
 | 
			
		||||
   have moved here. See #1993
 | 
			
		||||
 - *oemid* now uses consistent variable replacement (e.g. KMacroExpander)
 | 
			
		||||
   and does not support `@@DATE@@` anymore (use `${DATE}`).
 | 
			
		||||
 - *partition* requires KPMCore 21.12 (e.g. KPMCore 4.2 API, or later).
 | 
			
		||||
 - *partition* can now skip installing the bootloader in more scenarios.
 | 
			
		||||
   #1632 (Thanks Anubhav)
 | 
			
		||||
 - *preservefiles* follows `${}` variable syntax instead of `@@`.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										726
									
								
								CMakeLists.txt
									
									
									
									
									
								
							
							
						
						
									
										726
									
								
								CMakeLists.txt
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,97 +0,0 @@
 | 
			
		||||
# === This file is part of Calamares - <https://calamares.io> ===
 | 
			
		||||
#
 | 
			
		||||
#   SPDX-FileCopyrightText: 2014 Aurélien Gâteau <agateau@kde.org>
 | 
			
		||||
#   SPDX-FileCopyrightText: 2017 Adriaan de Groot <groot@kde.org>
 | 
			
		||||
#   SPDX-FileCopyrightText: 2019 Kevin Kofler <kevin.kofler@chello.at>
 | 
			
		||||
#   SPDX-License-Identifier: BSD-2-Clause
 | 
			
		||||
#
 | 
			
		||||
###
 | 
			
		||||
#
 | 
			
		||||
# Handles the mess that Boost::Python is before CMake 3.16 and
 | 
			
		||||
# Boost 1.70 or so.
 | 
			
		||||
#
 | 
			
		||||
###
 | 
			
		||||
#
 | 
			
		||||
# On Ubuntu 14.04, the libboost-python1.54-dev package comes with one library
 | 
			
		||||
# for each Python version:
 | 
			
		||||
# libboost_python-py27.so
 | 
			
		||||
# libboost_python-py33.so
 | 
			
		||||
# libboost_python-py34.so
 | 
			
		||||
#
 | 
			
		||||
# Boost upstream however installs Boost.Python3 libboost_python3.so, which is
 | 
			
		||||
# what FindBoost.cmake is looking for. It looks for a library named
 | 
			
		||||
# "libboost_${component}.so".
 | 
			
		||||
#
 | 
			
		||||
# On Gentoo instead, the >=dev-libs/boost-1.54 package provides boost library
 | 
			
		||||
# with a name like:
 | 
			
		||||
# libboost_python-2.7.so
 | 
			
		||||
# libboost_python-3.3.so
 | 
			
		||||
# libboost_python-3.4.so
 | 
			
		||||
# depending on what python's targets you selected during install
 | 
			
		||||
#
 | 
			
		||||
# On Fedora >= 30 instead, the boost-python3-devel provides boost library with a
 | 
			
		||||
# name like:
 | 
			
		||||
# libboost_python37.so
 | 
			
		||||
# depending on what python's targets you selected during install
 | 
			
		||||
#
 | 
			
		||||
# find_boost_python3() tries to find the package with different component
 | 
			
		||||
# names. By default it tries "python3", "python-py$suffix" and
 | 
			
		||||
# "python-$dotsuffix", where suffix is based on the `python_version` argument.
 | 
			
		||||
# One can supply a custom component name by setting the
 | 
			
		||||
# `CALAMARES_BOOST_PYTHON3_COMPONENT` variable at CMake time.
 | 
			
		||||
set( CALAMARES_BOOST_PYTHON3_COMPONENT python3 CACHE STRING
 | 
			
		||||
    "Name of the Boost.Python component. If Boost.Python is installed as
 | 
			
		||||
    libboost_python-foo.so then this variable should be set to 'python-foo'."
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
include(FindPackageHandleStandardArgs)
 | 
			
		||||
 | 
			
		||||
macro( _find_boost_python3_int boost_version componentname found_var )
 | 
			
		||||
    foreach( _fbp_name ${CALAMARES_BOOST_PYTHON3_COMPONENT} ${componentname} )
 | 
			
		||||
        find_package( Boost ${boost_version} QUIET COMPONENTS ${_fbp_name} )
 | 
			
		||||
        string( TOUPPER ${_fbp_name} _fbp_uc_name )
 | 
			
		||||
        if( Boost_${_fbp_uc_name}_FOUND )
 | 
			
		||||
            if( CMAKE_SYSTEM_NAME MATCHES "FreeBSD" )
 | 
			
		||||
                # No upcasing
 | 
			
		||||
                set( ${found_var} ${_fbp_name} )
 | 
			
		||||
            else()
 | 
			
		||||
                set( ${found_var} ${_fbp_uc_name} )
 | 
			
		||||
            endif()
 | 
			
		||||
            break()
 | 
			
		||||
        endif()
 | 
			
		||||
    endforeach()
 | 
			
		||||
endmacro()
 | 
			
		||||
 | 
			
		||||
macro( find_boost_python3 boost_version python_version found_var )
 | 
			
		||||
    set( ${found_var} OFF )
 | 
			
		||||
    set( _fbp_found OFF )
 | 
			
		||||
 | 
			
		||||
    # turns "3.4.123abc" into "34"
 | 
			
		||||
    string( REGEX REPLACE "([0-9]+)\\.([0-9]+)\\..*" "\\1\\2" _fbp_python_short_version ${python_version} )
 | 
			
		||||
    _find_boost_python3_int( ${boost_version} python-py${_fbp_python_short_version} _fbp_found )
 | 
			
		||||
 | 
			
		||||
    if (NOT _fbp_found)
 | 
			
		||||
        _find_boost_python3_int( ${boost_version} python${_fbp_python_short_version} _fbp_found )
 | 
			
		||||
    endif()
 | 
			
		||||
 | 
			
		||||
    if (NOT _fbp_found)
 | 
			
		||||
        # The following loop changes the searched name for Gentoo based distributions
 | 
			
		||||
        # turns "3.4.123abc" into "3.4"
 | 
			
		||||
        string( REGEX REPLACE "([0-9]+)\\.([0-9]+)\\..*" "\\1.\\2" _fbp_python_short_version ${python_version} )
 | 
			
		||||
        _find_boost_python3_int( ${boost_version} python-${_fbp_python_short_version} _fbp_found )
 | 
			
		||||
    endif()
 | 
			
		||||
 | 
			
		||||
    set( ${found_var} ${_fbp_found} )
 | 
			
		||||
 | 
			
		||||
    # This is superfluous, but allows proper reporting in the features list
 | 
			
		||||
    if ( _fbp_found )
 | 
			
		||||
        find_package( Boost ${boost_version} COMPONENTS ${_fbp_found} )
 | 
			
		||||
    else()
 | 
			
		||||
        find_package( Boost ${boost_version} COMPONENTS Python )
 | 
			
		||||
    endif()
 | 
			
		||||
    set_package_properties(
 | 
			
		||||
        Boost PROPERTIES
 | 
			
		||||
        DESCRIPTION "A C++ library which enables seamless interoperability between C++ and Python 3."
 | 
			
		||||
        URL "http://www.boost.org"
 | 
			
		||||
    )
 | 
			
		||||
endmacro()
 | 
			
		||||
@@ -1,31 +0,0 @@
 | 
			
		||||
# === This file is part of Calamares - <https://calamares.io> ===
 | 
			
		||||
#
 | 
			
		||||
#   SPDX-FileCopyrightText: 2014 Teo Mrnjavac <teo@kde.org>
 | 
			
		||||
#   SPDX-License-Identifier: BSD-2-Clause
 | 
			
		||||
#
 | 
			
		||||
###
 | 
			
		||||
#
 | 
			
		||||
# Find today's date, for versioning purposes.
 | 
			
		||||
find_program(DATE_EXECUTABLE NAMES date)
 | 
			
		||||
mark_as_advanced(DATE_EXECUTABLE)
 | 
			
		||||
 | 
			
		||||
if(DATE_EXECUTABLE)
 | 
			
		||||
  execute_process(
 | 
			
		||||
    COMMAND ${DATE_EXECUTABLE} +%Y
 | 
			
		||||
    OUTPUT_VARIABLE CMAKE_DATESTAMP_YEAR
 | 
			
		||||
    OUTPUT_STRIP_TRAILING_WHITESPACE
 | 
			
		||||
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
 | 
			
		||||
  )
 | 
			
		||||
  execute_process(
 | 
			
		||||
    COMMAND ${DATE_EXECUTABLE} +%m
 | 
			
		||||
    OUTPUT_VARIABLE CMAKE_DATESTAMP_MONTH
 | 
			
		||||
    OUTPUT_STRIP_TRAILING_WHITESPACE
 | 
			
		||||
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
 | 
			
		||||
  )
 | 
			
		||||
  execute_process(
 | 
			
		||||
    COMMAND ${DATE_EXECUTABLE} +%d
 | 
			
		||||
    OUTPUT_VARIABLE CMAKE_DATESTAMP_DAY
 | 
			
		||||
    OUTPUT_STRIP_TRAILING_WHITESPACE
 | 
			
		||||
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
 | 
			
		||||
  )
 | 
			
		||||
endif()
 | 
			
		||||
@@ -1,52 +0,0 @@
 | 
			
		||||
# === This file is part of Calamares - <https://calamares.io> ===
 | 
			
		||||
#
 | 
			
		||||
#   SPDX-FileCopyrightText: 2014 Teo Mrnjavac <teo@kde.org>
 | 
			
		||||
#   SPDX-License-Identifier: BSD-2-Clause
 | 
			
		||||
#
 | 
			
		||||
###
 | 
			
		||||
#
 | 
			
		||||
# Try to identify the current development source version.
 | 
			
		||||
set(CMAKE_VERSION_SOURCE "")
 | 
			
		||||
if(EXISTS ${CMAKE_SOURCE_DIR}/.git/HEAD)
 | 
			
		||||
  find_program(GIT_EXECUTABLE NAMES git git.cmd)
 | 
			
		||||
  mark_as_advanced(GIT_EXECUTABLE)
 | 
			
		||||
  if(GIT_EXECUTABLE)
 | 
			
		||||
    execute_process(
 | 
			
		||||
      COMMAND ${GIT_EXECUTABLE} rev-parse --verify -q --short=7 HEAD
 | 
			
		||||
      OUTPUT_VARIABLE head
 | 
			
		||||
      OUTPUT_STRIP_TRAILING_WHITESPACE
 | 
			
		||||
      WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
 | 
			
		||||
      )
 | 
			
		||||
    if(head)
 | 
			
		||||
      set(branch "")
 | 
			
		||||
      execute_process(
 | 
			
		||||
        COMMAND ${GIT_EXECUTABLE} name-rev HEAD
 | 
			
		||||
        OUTPUT_VARIABLE branch
 | 
			
		||||
        OUTPUT_STRIP_TRAILING_WHITESPACE
 | 
			
		||||
        WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
 | 
			
		||||
        )
 | 
			
		||||
      string(REGEX REPLACE "HEAD " "" branch "${branch}")
 | 
			
		||||
      set(CMAKE_VERSION_SOURCE "git-${branch}-${head}")
 | 
			
		||||
      execute_process(
 | 
			
		||||
        COMMAND ${GIT_EXECUTABLE} update-index -q --refresh
 | 
			
		||||
        WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
 | 
			
		||||
        )
 | 
			
		||||
      execute_process(
 | 
			
		||||
        COMMAND ${GIT_EXECUTABLE} diff-index --name-only HEAD --
 | 
			
		||||
        OUTPUT_VARIABLE dirty
 | 
			
		||||
        OUTPUT_STRIP_TRAILING_WHITESPACE
 | 
			
		||||
        WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
 | 
			
		||||
        )
 | 
			
		||||
      if(dirty)
 | 
			
		||||
        set(CMAKE_VERSION_SOURCE "${CMAKE_VERSION_SOURCE}-dirty")
 | 
			
		||||
      endif()
 | 
			
		||||
    endif()
 | 
			
		||||
  endif()
 | 
			
		||||
elseif(EXISTS ${CMAKE_SOURCE_DIR}/CVS/Repository)
 | 
			
		||||
  file(READ ${CMAKE_SOURCE_DIR}/CVS/Repository repo)
 | 
			
		||||
  set(branch "")
 | 
			
		||||
  if("${repo}" MATCHES "\\.git/")
 | 
			
		||||
    string(REGEX REPLACE ".*\\.git/([^\r\n]*).*" "-\\1" branch "${repo}")
 | 
			
		||||
  endif()
 | 
			
		||||
  set(CMAKE_VERSION_SOURCE "cvs${branch}")
 | 
			
		||||
endif()
 | 
			
		||||
@@ -101,7 +101,7 @@ function( calamares_add_branding_translations NAME )
 | 
			
		||||
 | 
			
		||||
    file( GLOB BRANDING_TRANSLATION_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${SUBDIRECTORY}/lang/calamares-${NAME}_*.ts" )
 | 
			
		||||
    if ( BRANDING_TRANSLATION_FILES )
 | 
			
		||||
        qt5_add_translation( QM_FILES ${BRANDING_TRANSLATION_FILES} )
 | 
			
		||||
        qt_add_translation( QM_FILES ${BRANDING_TRANSLATION_FILES} )
 | 
			
		||||
        add_custom_target( branding-translation-${NAME} ALL DEPENDS ${QM_FILES}
 | 
			
		||||
            COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/${SUBDIRECTORY}/lang/
 | 
			
		||||
            COMMAND ${CMAKE_COMMAND} -E copy ${QM_FILES} ${CMAKE_CURRENT_BINARY_DIR}/${SUBDIRECTORY}/lang/
 | 
			
		||||
 
 | 
			
		||||
@@ -62,8 +62,10 @@ function(calamares_add_library)
 | 
			
		||||
        add_library(${target} STATIC ${LIBRARY_SOURCES})
 | 
			
		||||
    elseif(LIBRARY_TARGET_TYPE STREQUAL "MODULE")
 | 
			
		||||
        add_library(${target} MODULE ${LIBRARY_SOURCES})
 | 
			
		||||
    else() # default
 | 
			
		||||
    elseif(LIBRARY_TARGET_TYPE STREQUAL "SHARED")
 | 
			
		||||
        add_library(${target} SHARED ${LIBRARY_SOURCES})
 | 
			
		||||
    else() # default
 | 
			
		||||
        message(FATAL_ERROR "Invalid library type '${LIBRARY_TARGET_TYPE}'")
 | 
			
		||||
    endif()
 | 
			
		||||
 | 
			
		||||
    calamares_automoc(${target})
 | 
			
		||||
@@ -86,9 +88,9 @@ function(calamares_add_library)
 | 
			
		||||
    # add link targets
 | 
			
		||||
    target_link_libraries(${target}
 | 
			
		||||
        LINK_PUBLIC ${Calamares_LIBRARIES}
 | 
			
		||||
        Qt5::Core
 | 
			
		||||
        Qt5::Gui
 | 
			
		||||
        Qt5::Widgets
 | 
			
		||||
        ${qtname}::Core
 | 
			
		||||
        ${qtname}::Gui
 | 
			
		||||
        ${qtname}::Widgets
 | 
			
		||||
    )
 | 
			
		||||
    if(LIBRARY_LINK_LIBRARIES)
 | 
			
		||||
        target_link_libraries(${target} LINK_PUBLIC ${LIBRARY_LINK_LIBRARIES})
 | 
			
		||||
 
 | 
			
		||||
@@ -12,33 +12,83 @@
 | 
			
		||||
# Function and support code for adding a Calamares module (either a Qt / C++ plugin,
 | 
			
		||||
# or a Python module, or whatever) to the build.
 | 
			
		||||
#
 | 
			
		||||
# # Usage
 | 
			
		||||
#
 | 
			
		||||
# The public API is one single function:
 | 
			
		||||
#
 | 
			
		||||
# - calamares_add_module_subdirectory(subdirectory [skiplistvar])
 | 
			
		||||
#   Adds a given *subdirectory* to the modules list, building the
 | 
			
		||||
#   module that is there. The *subdirectory* must contain a `module.desc`
 | 
			
		||||
#   (generally non-C++ modules) or a `CMakeLists.txt` (for C++ modules,
 | 
			
		||||
#   or special cases). The module is assumed to be named after the
 | 
			
		||||
#   (last component of) the subdirectory.
 | 
			
		||||
#
 | 
			
		||||
#   If the module would be skipped (by the global SKIP_MODULES setting
 | 
			
		||||
#   or a USE_* setting) or the module itself sets a reason to skip
 | 
			
		||||
#   via the calamares_skip_module() function, the module is added to
 | 
			
		||||
#   the list of skipped-modules in *skiplistvar*. If no variable is
 | 
			
		||||
#   given, the reason is set in the parent scope variable
 | 
			
		||||
#   SKIPPED_MODULES . Do **not** use SKIPPED_MODULES as the name of
 | 
			
		||||
#   *skiplistvar*, things will get weird.
 | 
			
		||||
#
 | 
			
		||||
#   Do note that the name of a module must be the same as the name of
 | 
			
		||||
#   the directory containing it (as documented in src/modules/README.md).
 | 
			
		||||
#   This applies to both C++ and Python modules, and allows the use of
 | 
			
		||||
#   the subdirectory as a proxy for the module name inside.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
include( CalamaresAddTranslations )
 | 
			
		||||
include( CalamaresCheckModuleSelection )
 | 
			
		||||
 | 
			
		||||
set( MODULE_DATA_DESTINATION share/calamares/modules )
 | 
			
		||||
 | 
			
		||||
# Convenience function to indicate that a module has been skipped
 | 
			
		||||
# (optionally also why). Call this in the module's CMakeLists.txt
 | 
			
		||||
macro( calamares_skip_module )
 | 
			
		||||
    set( SKIPPED_MODULES ${SKIPPED_MODULES} ${ARGV} PARENT_SCOPE )
 | 
			
		||||
endmacro()
 | 
			
		||||
# We look for Pylint (just once) so that unittests can be added that
 | 
			
		||||
# check the syntax / variables of Python modules. This should help
 | 
			
		||||
# avoid more typo's-in-releases.
 | 
			
		||||
if(BUILD_TESTING AND NOT PYLINT_COMMAND_SEARCHED)
 | 
			
		||||
    set(PYLINT_COMMAND_SEARCHED TRUE)
 | 
			
		||||
    find_program(
 | 
			
		||||
        PYLINT_COMMAND
 | 
			
		||||
        NAMES pylint3 pylint
 | 
			
		||||
        PATHS $ENV{HOME}/.local/bin
 | 
			
		||||
        )
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
function( calamares_explain_skipped_modules )
 | 
			
		||||
    if ( ARGN )
 | 
			
		||||
        message( "${ColorReset}-- Skipped modules:" )
 | 
			
		||||
        foreach( SUBDIRECTORY ${ARGN} )
 | 
			
		||||
            message( "${ColorReset}--   Skipped ${BoldRed}${SUBDIRECTORY}${ColorReset}." )
 | 
			
		||||
        endforeach()
 | 
			
		||||
        message( "" )
 | 
			
		||||
    endif()
 | 
			
		||||
endfunction()
 | 
			
		||||
 | 
			
		||||
function( calamares_add_module_subdirectory )
 | 
			
		||||
function( _calamares_add_module_subdirectory_impl )
 | 
			
		||||
    set( SUBDIRECTORY ${ARGV0} )
 | 
			
		||||
 | 
			
		||||
    set( SKIPPED_MODULES )
 | 
			
		||||
    # Set SKIPPED_MODULES here, so CMake-based modules have a
 | 
			
		||||
    # parent scope to set it in; this function, in turn sets it
 | 
			
		||||
    # in **its** parent scope.
 | 
			
		||||
    set( SKIPPED_MODULES "" )
 | 
			
		||||
    set( MODULE_CONFIG_FILES "" )
 | 
			
		||||
 | 
			
		||||
    # The module subdirectory may be given as a/b/c, but the module
 | 
			
		||||
    # needs to be installed as "c", so we split off any intermediate
 | 
			
		||||
    # directories.
 | 
			
		||||
    #
 | 
			
		||||
    # Compute _modulename (the last directory name) and _mod_dir
 | 
			
		||||
    # (the full path to the module sources).
 | 
			
		||||
    get_filename_component(_dirname "${SUBDIRECTORY}" DIRECTORY)
 | 
			
		||||
    if( _dirname )
 | 
			
		||||
        # Remove the dirname and any leftover leading /s
 | 
			
		||||
        string( REGEX REPLACE "^${_dirname}/*" "" _modulename "${SUBDIRECTORY}" )
 | 
			
		||||
    else()
 | 
			
		||||
        set( _modulename ${SUBDIRECTORY} )
 | 
			
		||||
    endif()
 | 
			
		||||
    # Strip any remaining /
 | 
			
		||||
    string( REGEX REPLACE "/" "" _modulename "${_modulename}" )
 | 
			
		||||
    set( _mod_dir "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIRECTORY}" )
 | 
			
		||||
 | 
			
		||||
    # Skip list check applies to all kinds of modules
 | 
			
		||||
    calamares_check_skip( ${_modulename} SKIPPED_MODULES )
 | 
			
		||||
    if ( SKIPPED_MODULES )
 | 
			
		||||
        # If it's skipped by infrastucture, the message already includes the module
 | 
			
		||||
        # name. We don't need to do any further checking.
 | 
			
		||||
        set( SKIPPED_MODULES "${SKIPPED_MODULES}" PARENT_SCOPE )
 | 
			
		||||
        return()
 | 
			
		||||
    endif()
 | 
			
		||||
 | 
			
		||||
    # If this subdirectory has a CMakeLists.txt, we add_subdirectory it...
 | 
			
		||||
    if( EXISTS "${_mod_dir}/CMakeLists.txt" )
 | 
			
		||||
        add_subdirectory( ${SUBDIRECTORY} )
 | 
			
		||||
@@ -48,21 +98,21 @@ function( calamares_add_module_subdirectory )
 | 
			
		||||
        if ( SKIPPED_MODULES )
 | 
			
		||||
            set( SKIPPED_MODULES ${SKIPPED_MODULES} PARENT_SCOPE )
 | 
			
		||||
            set( MODULE_CONFIG_FILES "" )
 | 
			
		||||
        else()
 | 
			
		||||
            # The SKIPPED_MODULES may be set in the directory itself
 | 
			
		||||
            get_directory_property( _skip DIRECTORY ${SUBDIRECTORY} DEFINITION SKIPPED_MODULES )
 | 
			
		||||
            if ( _skip )
 | 
			
		||||
                set( SKIPPED_MODULES ${_skip} PARENT_SCOPE )
 | 
			
		||||
                set( MODULE_CONFIG_FILES "" )
 | 
			
		||||
            endif()
 | 
			
		||||
        endif()
 | 
			
		||||
        if ( SKIPPED_MODULES )
 | 
			
		||||
            return()
 | 
			
		||||
        endif()
 | 
			
		||||
    # ...otherwise, we look for a module.desc.
 | 
			
		||||
    elseif( EXISTS "${_mod_dir}/module.desc" )
 | 
			
		||||
        set( MODULES_DIR ${CMAKE_INSTALL_LIBDIR}/calamares/modules )
 | 
			
		||||
        # The module subdirectory may be given as a/b/c, but the module
 | 
			
		||||
        # needs to be installed as "c", so we split off any intermediate
 | 
			
		||||
        # directories.
 | 
			
		||||
        get_filename_component(_dirname "${SUBDIRECTORY}" DIRECTORY)
 | 
			
		||||
        if( _dirname )
 | 
			
		||||
            # Remove the dirname and any leftover leading /s
 | 
			
		||||
            string( REGEX REPLACE "^${_dirname}/*" "" _modulename "${SUBDIRECTORY}" )
 | 
			
		||||
            set( MODULE_DESTINATION ${MODULES_DIR}/${_modulename} )
 | 
			
		||||
        else()
 | 
			
		||||
            set( MODULE_DESTINATION ${MODULES_DIR}/${SUBDIRECTORY} )
 | 
			
		||||
        endif()
 | 
			
		||||
        set( MODULE_DESTINATION ${MODULES_DIR}/${_modulename} )
 | 
			
		||||
 | 
			
		||||
        # Read module.desc, check that the interface type is supported.
 | 
			
		||||
        #
 | 
			
		||||
@@ -71,7 +121,8 @@ function( calamares_add_module_subdirectory )
 | 
			
		||||
        # _mod_testing boolean if the module should be added to the loadmodule tests
 | 
			
		||||
        file(STRINGS "${_mod_dir}/module.desc" MODULE_INTERFACE REGEX "^interface")
 | 
			
		||||
        if ( MODULE_INTERFACE MATCHES "pythonqt" )
 | 
			
		||||
            set( _mod_enabled ${Calamares_WITH_PYTHONQT} )
 | 
			
		||||
            message( FATAL_ERROR "PythonQt is no longer supported" )
 | 
			
		||||
            set( _mod_enabled OFF )
 | 
			
		||||
            set( _mod_reason "No PythonQt support" )
 | 
			
		||||
            set( _mod_testing OFF )
 | 
			
		||||
        elseif ( MODULE_INTERFACE MATCHES "python" )
 | 
			
		||||
@@ -102,28 +153,28 @@ function( calamares_add_module_subdirectory )
 | 
			
		||||
 | 
			
		||||
                    get_filename_component( FLEXT ${MODULE_FILE} EXT )
 | 
			
		||||
                    if( "${FLEXT}" STREQUAL ".conf" )
 | 
			
		||||
                        if( INSTALL_CONFIG )
 | 
			
		||||
                            install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${SUBDIRECTORY}/${MODULE_FILE}
 | 
			
		||||
                                    DESTINATION ${MODULE_DATA_DESTINATION} )
 | 
			
		||||
                        endif()
 | 
			
		||||
                        message(STATUS "Config ${MODULE_FILE}")
 | 
			
		||||
                        list( APPEND MODULE_CONFIG_FILES ${MODULE_FILE} )
 | 
			
		||||
                    else()
 | 
			
		||||
                        message(STATUS "Non-Config ${MODULE_FILE}")
 | 
			
		||||
                        install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${SUBDIRECTORY}/${MODULE_FILE}
 | 
			
		||||
                                 DESTINATION ${MODULE_DESTINATION} )
 | 
			
		||||
                    endif()
 | 
			
		||||
                endif()
 | 
			
		||||
            endforeach()
 | 
			
		||||
 | 
			
		||||
            message( "-- ${BoldYellow}Found ${CALAMARES_APPLICATION_NAME} module: ${BoldRed}${SUBDIRECTORY}${ColorReset}" )
 | 
			
		||||
            message( "-- ${BoldYellow}Found ${CALAMARES_APPLICATION_NAME} module: ${BoldRed}${_modulename}${ColorReset}" )
 | 
			
		||||
            message( "   ${Green}TYPE:${ColorReset} jobmodule" )
 | 
			
		||||
            message( "   ${Green}MODULE_DESTINATION:${ColorReset} ${MODULE_DESTINATION}" )
 | 
			
		||||
            if( MODULE_CONFIG_FILES )
 | 
			
		||||
                if ( INSTALL_CONFIG )
 | 
			
		||||
                    set( _destination "${MODULE_DATA_DESTINATION}" )
 | 
			
		||||
                if (INSTALL_CONFIG)
 | 
			
		||||
                    message("   ${Green}CONFIGURATION_FILES:${ColorReset} ${MODULE_CONFIG_FILES} => [Build directory and ${MODULE_DATA_DESTINATION}]")
 | 
			
		||||
                    foreach(_cf ${MODULE_CONFIG_FILES})
 | 
			
		||||
                        install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SUBDIRECTORY}/${_cf} DESTINATION ${MODULE_DATA_DESTINATION})
 | 
			
		||||
                    endforeach()
 | 
			
		||||
                else()
 | 
			
		||||
                    set( _destination "[Build directory only]" )
 | 
			
		||||
                    message("   ${Green}CONFIGURATION_FILES:${ColorReset} ${MODULE_CONFIG_FILES} => [Build directory only]")
 | 
			
		||||
                endif()
 | 
			
		||||
                message( "   ${Green}CONFIGURATION_FILES:${ColorReset} ${MODULE_CONFIG_FILES} => ${_destination}" )
 | 
			
		||||
            endif()
 | 
			
		||||
            message( "" )
 | 
			
		||||
            # We copy over the lang directory, if any
 | 
			
		||||
@@ -159,7 +210,9 @@ function( calamares_add_module_subdirectory )
 | 
			
		||||
        endforeach()
 | 
			
		||||
    endif()
 | 
			
		||||
 | 
			
		||||
    # Check that the module can be loaded. Since this calls exec(), the module
 | 
			
		||||
    # Adding general tests
 | 
			
		||||
    #
 | 
			
		||||
    # Add a check that the module can be loaded. Since this calls exec(), the module
 | 
			
		||||
    # may try to do things to the running system. Needs work to make that a
 | 
			
		||||
    # safe thing to do.
 | 
			
		||||
    #
 | 
			
		||||
@@ -201,5 +254,34 @@ function( calamares_add_module_subdirectory )
 | 
			
		||||
        if ( EXISTS ${_testdir}/CMakeTests.txt AND NOT EXISTS ${_mod_dir}/CMakeLists.txt )
 | 
			
		||||
            include( ${_testdir}/CMakeTests.txt )
 | 
			
		||||
        endif()
 | 
			
		||||
        if ( PYLINT_COMMAND AND MODULE_INTERFACE MATCHES "python" )
 | 
			
		||||
            # Python modules get an additional test via pylint; this
 | 
			
		||||
            # needs to run at top-level because the ci/libcalamares directory
 | 
			
		||||
            # contains API stubs.
 | 
			
		||||
            #
 | 
			
		||||
            # TODO: the entry point is assumed to be `main.py`, but that is
 | 
			
		||||
            #       configurable through module.desc
 | 
			
		||||
            add_test(
 | 
			
		||||
                NAME lint-${SUBDIRECTORY}
 | 
			
		||||
                COMMAND env PYTHONPATH=ci: ${PYLINT_COMMAND} -E ${_mod_dir}/main.py
 | 
			
		||||
                WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
 | 
			
		||||
                )
 | 
			
		||||
        endif()
 | 
			
		||||
    endif()
 | 
			
		||||
endfunction()
 | 
			
		||||
 | 
			
		||||
function( calamares_add_module_subdirectory )
 | 
			
		||||
    set( SUBDIRECTORY ${ARGV0} )
 | 
			
		||||
    set( _ams_SKIP_LIST ${ARGV1} )
 | 
			
		||||
 | 
			
		||||
    set( SKIPPED_MODULES "" )
 | 
			
		||||
    _calamares_add_module_subdirectory_impl( ${SUBDIRECTORY} )
 | 
			
		||||
    if ( SKIPPED_MODULES )
 | 
			
		||||
        if ( _ams_SKIP_LIST )
 | 
			
		||||
            list( APPEND ${_ams_SKIP_LIST} "${SKIPPED_MODULES}" )
 | 
			
		||||
            set( ${_ams_SKIP_LIST} "${${_ams_SKIP_LIST}}" PARENT_SCOPE )
 | 
			
		||||
        else()
 | 
			
		||||
            set( SKIPPED_MODULES "${SKIPPED_MODULES}" PARENT_SCOPE )
 | 
			
		||||
        endif()
 | 
			
		||||
    endif()
 | 
			
		||||
endfunction()
 | 
			
		||||
 
 | 
			
		||||
@@ -59,9 +59,17 @@
 | 
			
		||||
#       If this is set, writes an explicit weight into the module.desc;
 | 
			
		||||
#       module weights are used in progress reporting.
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
# This function follows the global SKIP_MODULES and USE_* settings, so
 | 
			
		||||
# a plugin may be skipped -- then nothing will be built. In that case,
 | 
			
		||||
# SKIPPED_MODULES is set in the parent (i.e. caller's) scope with the
 | 
			
		||||
# reason why. This should rarely be a concern as AddModuleSubdirectory
 | 
			
		||||
# already handles skip-reasons and collects them for reporting.
 | 
			
		||||
 | 
			
		||||
include( CMakeParseArguments )
 | 
			
		||||
 | 
			
		||||
include( CalamaresAddLibrary  )
 | 
			
		||||
include( CalamaresCheckModuleSelection )
 | 
			
		||||
include( CMakeColors )
 | 
			
		||||
 | 
			
		||||
function( calamares_add_plugin )
 | 
			
		||||
@@ -80,6 +88,12 @@ function( calamares_add_plugin )
 | 
			
		||||
    set( CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" )
 | 
			
		||||
    set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" )
 | 
			
		||||
 | 
			
		||||
    calamares_check_skip( ${NAME} _skip)
 | 
			
		||||
    if ( _skip )
 | 
			
		||||
        set( SKIPPED_MODULES "${_skip}" PARENT_SCOPE )
 | 
			
		||||
        return()
 | 
			
		||||
    endif()
 | 
			
		||||
 | 
			
		||||
    message( "-- ${BoldYellow}Found ${CALAMARES_APPLICATION_NAME} module: ${BoldRed}${PLUGIN_NAME}${ColorReset}" )
 | 
			
		||||
    message( "   ${Green}TYPE:${ColorReset} ${PLUGIN_TYPE}" )
 | 
			
		||||
    message( "   ${Green}LINK_LIBRARIES:${ColorReset} ${PLUGIN_LINK_LIBRARIES}" )
 | 
			
		||||
@@ -90,10 +104,9 @@ function( calamares_add_plugin )
 | 
			
		||||
            message( FATAL_ERROR "${Red}NO_CONFIG${ColorReset} is set, with configuration ${Red}${PLUGIN_CONFIG_FILES}${ColorReset}" )
 | 
			
		||||
        endif()
 | 
			
		||||
        set( _destination "(unknown)" )
 | 
			
		||||
        if ( INSTALL_CONFIG AND NOT PLUGIN_NO_INSTALL )
 | 
			
		||||
            set( _destination "${PLUGIN_DATA_DESTINATION}" )
 | 
			
		||||
        if(INSTALL_CONFIG AND NOT PLUGIN_NO_INSTALL)
 | 
			
		||||
            set(_destination "${PLUGIN_DATA_DESTINATION}")
 | 
			
		||||
        elseif( NOT PLUGIN_NO_INSTALL )
 | 
			
		||||
            # Not INSTALL_CONFIG
 | 
			
		||||
            set( _destination "[Build directory only]" )
 | 
			
		||||
        else()
 | 
			
		||||
            set( _destination "[Skipping installation]" )
 | 
			
		||||
@@ -112,6 +125,15 @@ function( calamares_add_plugin )
 | 
			
		||||
    # create target name once for convenience
 | 
			
		||||
    set( target "calamares_${PLUGIN_TYPE}_${PLUGIN_NAME}" )
 | 
			
		||||
 | 
			
		||||
    # automatic library linkage
 | 
			
		||||
    if(PLUGIN_TYPE STREQUAL "view" OR PLUGIN_TYPE STREQUAL "viewmodule")
 | 
			
		||||
        list(APPEND PLUGIN_LINK_PRIVATE_LIBRARIES Calamares::calamaresui)
 | 
			
		||||
    elseif(PLUGIN_TYPE STREQUAL "job")
 | 
			
		||||
        list(APPEND PLUGIN_LINK_PRIVATE_LIBRARIES Calamares::calamares)
 | 
			
		||||
    else()
 | 
			
		||||
        message(FATAL_ERROR "Unknown plugin type ${PLUGIN_TYPE}")
 | 
			
		||||
    endif()
 | 
			
		||||
 | 
			
		||||
    # determine target type
 | 
			
		||||
    if( NOT ${PLUGIN_SHARED_LIB} )
 | 
			
		||||
        set( target_type "MODULE" )
 | 
			
		||||
@@ -187,16 +209,14 @@ function( calamares_add_plugin )
 | 
			
		||||
 | 
			
		||||
        set( _warned_config OFF )
 | 
			
		||||
        foreach( PLUGIN_CONFIG_FILE ${PLUGIN_CONFIG_FILES} )
 | 
			
		||||
            if( ${CMAKE_CURRENT_SOURCE_DIR}/${PLUGIN_CONFIG_FILE} IS_NEWER_THAN ${CMAKE_CURRENT_BINARY_DIR}/${PLUGIN_CONFIG_FILE} OR INSTALL_CONFIG )
 | 
			
		||||
            if( ${CMAKE_CURRENT_SOURCE_DIR}/${PLUGIN_CONFIG_FILE} IS_NEWER_THAN ${CMAKE_CURRENT_BINARY_DIR}/${PLUGIN_CONFIG_FILE} )
 | 
			
		||||
                configure_file( ${PLUGIN_CONFIG_FILE} ${PLUGIN_CONFIG_FILE} COPYONLY )
 | 
			
		||||
            else()
 | 
			
		||||
                message( "   ${BoldYellow}Not updating${ColorReset} ${PLUGIN_CONFIG_FILE}" )
 | 
			
		||||
                set( _warned_config ON )
 | 
			
		||||
            endif()
 | 
			
		||||
            if ( INSTALL_CONFIG )
 | 
			
		||||
                install(
 | 
			
		||||
                    FILES ${CMAKE_CURRENT_BINARY_DIR}/${PLUGIN_CONFIG_FILE}
 | 
			
		||||
                    DESTINATION ${PLUGIN_DATA_DESTINATION} )
 | 
			
		||||
            if(INSTALL_CONFIG)
 | 
			
		||||
                install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PLUGIN_CONFIG_FILE} DESTINATION ${PLUGIN_DATA_DESTINATION})
 | 
			
		||||
            endif()
 | 
			
		||||
        endforeach()
 | 
			
		||||
        if ( _warned_config )
 | 
			
		||||
 
 | 
			
		||||
@@ -18,37 +18,38 @@
 | 
			
		||||
#   SOURCES <FILE..>
 | 
			
		||||
#   )
 | 
			
		||||
 | 
			
		||||
include( CMakeParseArguments )
 | 
			
		||||
include( CalamaresAutomoc )
 | 
			
		||||
include(CMakeParseArguments)
 | 
			
		||||
include(CalamaresAutomoc)
 | 
			
		||||
 | 
			
		||||
function( calamares_add_test )
 | 
			
		||||
    # parse arguments (name needs to be saved before passing ARGN into the macro)
 | 
			
		||||
    set( NAME ${ARGV0} )
 | 
			
		||||
    set( options GUI )
 | 
			
		||||
    set( oneValueArgs NAME RESOURCES )
 | 
			
		||||
    set( multiValueArgs SOURCES LIBRARIES DEFINITIONS )
 | 
			
		||||
    cmake_parse_arguments( TEST "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
 | 
			
		||||
    set( TEST_NAME ${NAME} )
 | 
			
		||||
function(calamares_add_test name)
 | 
			
		||||
    set(options GUI)
 | 
			
		||||
    set(oneValueArgs RESOURCES)
 | 
			
		||||
    set(multiValueArgs SOURCES LIBRARIES DEFINITIONS)
 | 
			
		||||
    cmake_parse_arguments(TEST "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
 | 
			
		||||
    set(TEST_NAME ${name})
 | 
			
		||||
 | 
			
		||||
    if( ECM_FOUND AND BUILD_TESTING )
 | 
			
		||||
    if(ECM_FOUND AND BUILD_TESTING)
 | 
			
		||||
        ecm_add_test(
 | 
			
		||||
            ${TEST_SOURCES} ${TEST_RESOURCES}
 | 
			
		||||
            TEST_NAME
 | 
			
		||||
                ${TEST_NAME}
 | 
			
		||||
            LINK_LIBRARIES
 | 
			
		||||
                calamares
 | 
			
		||||
                Calamares::calamares
 | 
			
		||||
                ${TEST_LIBRARIES}
 | 
			
		||||
                Qt5::Core
 | 
			
		||||
                Qt5::Test
 | 
			
		||||
            )
 | 
			
		||||
                ${qtname}::Core
 | 
			
		||||
                ${qtname}::Test
 | 
			
		||||
        )
 | 
			
		||||
        calamares_automoc( ${TEST_NAME} )
 | 
			
		||||
        # We specifically pass in the source directory of the test-being-
 | 
			
		||||
        # compiled, so that it can find test-files in that source dir.
 | 
			
		||||
        target_compile_definitions( ${TEST_NAME} PRIVATE -DBUILD_AS_TEST="${CMAKE_CURRENT_SOURCE_DIR}"  ${TEST_DEFINITIONS} )
 | 
			
		||||
        if( TEST_GUI )
 | 
			
		||||
            target_link_libraries( ${TEST_NAME} calamaresui Qt5::Gui )
 | 
			
		||||
        target_compile_definitions(
 | 
			
		||||
            ${TEST_NAME}
 | 
			
		||||
            PRIVATE -DBUILD_AS_TEST="${CMAKE_CURRENT_SOURCE_DIR}" ${TEST_DEFINITIONS}
 | 
			
		||||
        )
 | 
			
		||||
        if(TEST_GUI)
 | 
			
		||||
            target_link_libraries(${TEST_NAME} Calamares::calamaresui ${qtname}::Gui)
 | 
			
		||||
        endif()
 | 
			
		||||
        if( TEST_RESOURCES )
 | 
			
		||||
        if(TEST_RESOURCES)
 | 
			
		||||
            calamares_autorcc( ${TEST_NAME} ${TEST_RESOURCES} )
 | 
			
		||||
        endif()
 | 
			
		||||
    endif()
 | 
			
		||||
 
 | 
			
		||||
@@ -100,3 +100,58 @@ function( install_calamares_gettext_translations )
 | 
			
		||||
        endif()
 | 
			
		||||
    endforeach()
 | 
			
		||||
endfunction()
 | 
			
		||||
 | 
			
		||||
set(_calamares_qrc_translations_qrc_source ${CMAKE_CURRENT_LIST_DIR}/i18n.qrc.in) # Needs to be set outside of function
 | 
			
		||||
function(calamares_qrc_translations basename)
 | 
			
		||||
    set(options "")
 | 
			
		||||
    set(oneValueArgs SUBDIRECTORY OUTPUT_VARIABLE)
 | 
			
		||||
    set(multiValueArgs PREFIXES LANGUAGES)
 | 
			
		||||
    cmake_parse_arguments(_qrt "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
 | 
			
		||||
 | 
			
		||||
    if(NOT _qrt_OUTPUT_VARIABLE)
 | 
			
		||||
        message(FATAL_ERROR "No output variable")
 | 
			
		||||
    endif()
 | 
			
		||||
    if(NOT _qrt_PREFIXES)
 | 
			
		||||
        set(_qrt_PREFIXES "${basename}")
 | 
			
		||||
    endif()
 | 
			
		||||
    if(NOT _qrt_LANGUAGES)
 | 
			
		||||
        set(_qrt_LANGUAGES ${CALAMARES_TRANSLATION_LANGUAGES})
 | 
			
		||||
    endif()
 | 
			
		||||
    if(NOT _qrt_SUBDIRECTORY)
 | 
			
		||||
        set(_qrt_SUBDIRECTORY "")
 | 
			
		||||
    endif()
 | 
			
		||||
 | 
			
		||||
    set(translations_qrc_infile ${CMAKE_CURRENT_BINARY_DIR}/${basename}.qrc)
 | 
			
		||||
    set(translations_qrc_outfile ${CMAKE_CURRENT_BINARY_DIR}/qrc_${basename}.cxx)
 | 
			
		||||
 | 
			
		||||
    # Must use this variable name because of the @ substitution
 | 
			
		||||
    set(calamares_i18n_qrc_content "")
 | 
			
		||||
    set(calamares_i18n_ts_filelist "")
 | 
			
		||||
    foreach(lang ${_qrt_LANGUAGES})
 | 
			
		||||
        foreach(tlsource ${_qrt_PREFIXES})
 | 
			
		||||
            if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${_qrt_SUBDIRECTORY}/${tlsource}_${lang}.ts")
 | 
			
		||||
                string(APPEND calamares_i18n_qrc_content "<file>${tlsource}_${lang}.qm</file>\n")
 | 
			
		||||
                list(APPEND calamares_i18n_ts_filelist "${CMAKE_CURRENT_SOURCE_DIR}/${_qrt_SUBDIRECTORY}/${tlsource}_${lang}.ts")
 | 
			
		||||
            endif()
 | 
			
		||||
        endforeach()
 | 
			
		||||
    endforeach()
 | 
			
		||||
 | 
			
		||||
    configure_file(${_calamares_qrc_translations_qrc_source} ${translations_qrc_infile} @ONLY)
 | 
			
		||||
    qt_add_translation(QM_FILES ${calamares_i18n_ts_filelist})
 | 
			
		||||
 | 
			
		||||
    # Run the resource compiler (rcc_options should already be set)
 | 
			
		||||
    add_custom_command(
 | 
			
		||||
        OUTPUT ${translations_qrc_outfile}
 | 
			
		||||
        COMMAND ${qtname}::rcc
 | 
			
		||||
        ARGS
 | 
			
		||||
            ${rcc_options}
 | 
			
		||||
            --format-version 1
 | 
			
		||||
            -name ${basename}
 | 
			
		||||
            -o ${translations_qrc_outfile}
 | 
			
		||||
            ${translations_qrc_infile}
 | 
			
		||||
        MAIN_DEPENDENCY ${translations_qrc_infile}
 | 
			
		||||
        DEPENDS ${QM_FILES}
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    set(${_qrt_OUTPUT_VARIABLE} ${translations_qrc_outfile} PARENT_SCOPE)
 | 
			
		||||
endfunction()
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										116
									
								
								CMakeModules/CalamaresCheckModuleSelection.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								CMakeModules/CalamaresCheckModuleSelection.cmake
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,116 @@
 | 
			
		||||
# === This file is part of Calamares - <https://calamares.io> ===
 | 
			
		||||
#
 | 
			
		||||
#   SPDX-FileCopyrightText: 2014 Teo Mrnjavac <teo@kde.org>
 | 
			
		||||
#   SPDX-FileCopyrightText: 2017 Adriaan de Groot <groot@kde.org>
 | 
			
		||||
#   SPDX-License-Identifier: BSD-2-Clause
 | 
			
		||||
#
 | 
			
		||||
#   Calamares is Free Software: see the License-Identifier above.
 | 
			
		||||
#
 | 
			
		||||
###
 | 
			
		||||
#
 | 
			
		||||
# This module implements the "skip modules" part of configuring
 | 
			
		||||
# the Calamares repository or an external-modules repository.
 | 
			
		||||
#
 | 
			
		||||
# It should not be necessary to include() this module explicitly,
 | 
			
		||||
# since both AddPlugin and AddModuleSubdirectory do so implicitly.
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
# # Usage
 | 
			
		||||
#
 | 
			
		||||
# The public API is two functions:
 | 
			
		||||
#
 | 
			
		||||
# - calamares_skip_module(reason)
 | 
			
		||||
#   A C++ module (or any that uses CMake) can call this macro to
 | 
			
		||||
#   add *reason* to the list of skipped modules. Typically a module
 | 
			
		||||
#   will pass in "modulename (why)" so that it is clear **which**
 | 
			
		||||
#   module is skipped. This macro should be called at the top-level
 | 
			
		||||
#   of a module's CMakeLists.txt and the module should then **not**
 | 
			
		||||
#   call calamares_add_plugin().
 | 
			
		||||
# - calamares_explain_skipped_modules(list...)
 | 
			
		||||
#   This will print out all the module reasons (see above) that have
 | 
			
		||||
#   been added to the given *listvar*. When AddModuleSubdirectory is
 | 
			
		||||
#   used as the mechanism to add all the subdirectories in the repository
 | 
			
		||||
#   that contain modules, with a consistent *listvar* setting,
 | 
			
		||||
#   this will show all the modules that have been skipped.
 | 
			
		||||
#
 | 
			
		||||
# The internal API is one function:
 | 
			
		||||
#
 | 
			
		||||
# - calamares_check_skip(modulename outvar)
 | 
			
		||||
#   Checks if the *modulename* has been listed in the global SKIP_MODULES
 | 
			
		||||
#   variable (to skip specifically-named modules) or if there is a USE_*
 | 
			
		||||
#   setting applicable to the module. If the module is skipped for this
 | 
			
		||||
#   reason, a suitable entry is added to *outvar* as if
 | 
			
		||||
#   calamares_skip_module() had been called.
 | 
			
		||||
#
 | 
			
		||||
# Best practice is to pick a variable to collect all of the skipped
 | 
			
		||||
# modules, and to pass the name of that variable to AddModuleSubdirectory
 | 
			
		||||
# in each call. After all subdirectories have been added, call
 | 
			
		||||
# calamares_explain_skipped_modules() with the value of that variable.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Convenience function to indicate that a module has been skipped
 | 
			
		||||
# (optionally also why). Call this in the module's CMakeLists.txt
 | 
			
		||||
macro( calamares_skip_module )
 | 
			
		||||
    set( SKIPPED_MODULES ${SKIPPED_MODULES} ${ARGV} PARENT_SCOPE )
 | 
			
		||||
endmacro()
 | 
			
		||||
 | 
			
		||||
function( calamares_explain_skipped_modules )
 | 
			
		||||
    if ( ARGN )
 | 
			
		||||
        message( "${ColorReset}-- Skipped modules:" )
 | 
			
		||||
        foreach( SUBDIRECTORY ${ARGN} )
 | 
			
		||||
            message( "${ColorReset}--   Skipped ${BoldRed}${SUBDIRECTORY}${ColorReset}." )
 | 
			
		||||
        endforeach()
 | 
			
		||||
        message( "" )
 | 
			
		||||
    endif()
 | 
			
		||||
endfunction()
 | 
			
		||||
 | 
			
		||||
# Globally, SKIP_MODULES and USE_* affect what modules are built.
 | 
			
		||||
# Check if *modulename* should be skipped, and if so, set *outvar* to
 | 
			
		||||
# a human-readable reason for skipping it.
 | 
			
		||||
function( _calamares_check_skip_impl modulename outvar )
 | 
			
		||||
    # Globally-defined SKIP_MODULES may be space- or semicolon- separated
 | 
			
		||||
    # so convert it to a list-variable.
 | 
			
		||||
    string( REPLACE " " ";" SKIP_LIST "${SKIP_MODULES}" )
 | 
			
		||||
 | 
			
		||||
    list( FIND SKIP_LIST "${modulename}" DO_SKIP )
 | 
			
		||||
    if( NOT DO_SKIP EQUAL -1 )
 | 
			
		||||
        set( ${outvar} "user request" PARENT_SCOPE )
 | 
			
		||||
        return()
 | 
			
		||||
    endif()
 | 
			
		||||
 | 
			
		||||
    # Not skipped by the global check, see if it has an applicable USE_*
 | 
			
		||||
    if( "${modulename}" MATCHES "^[a-zA-Z0-9_]+-" )
 | 
			
		||||
        # Split the name into <category>-<implementation>
 | 
			
		||||
        string( REGEX REPLACE "-.*" "" _category "${modulename}" )
 | 
			
		||||
        string( REGEX REPLACE "^[^-]+-" "" _implementation "${modulename}" )
 | 
			
		||||
    else()
 | 
			
		||||
        # Not a module to which USE_* applies
 | 
			
		||||
        return()
 | 
			
		||||
    endif()
 | 
			
		||||
 | 
			
		||||
    if( "${USE_${_category}}" STREQUAL "none" )
 | 
			
		||||
        set( ${outvar} "category ${_category} disabled" PARENT_SCOPE )
 | 
			
		||||
        return()
 | 
			
		||||
    elseif( "${USE_${_category}}" STREQUAL "" )
 | 
			
		||||
        # Category not set at all or nonexistent
 | 
			
		||||
        return()
 | 
			
		||||
    endif()
 | 
			
		||||
 | 
			
		||||
    if ( "${USE_${_category}}" STREQUAL "${_implementation}" )
 | 
			
		||||
        # Matches, so accept this module
 | 
			
		||||
    else()
 | 
			
		||||
        set( ${outvar} "category ${_category} selects ${USE_${_category}}" PARENT_SCOPE )
 | 
			
		||||
    endif()
 | 
			
		||||
endfunction()
 | 
			
		||||
 | 
			
		||||
# This is the public API;it calls the _impl version so that there
 | 
			
		||||
# is an extra intermediate scope for the subdirectory to write results into.
 | 
			
		||||
function( calamares_check_skip modulename outvar )
 | 
			
		||||
    set( _skip "" )
 | 
			
		||||
    _calamares_check_skip_impl( "${modulename}" _skip )
 | 
			
		||||
    if ( _skip )
 | 
			
		||||
        message( "${ColorReset}-- Skipping module ${BoldRed}${modulename} (${_skip})${ColorReset}." )
 | 
			
		||||
        message( "" )
 | 
			
		||||
        set( ${outvar} "${modulename} (${_skip})" PARENT_SCOPE )
 | 
			
		||||
    endif()
 | 
			
		||||
endfunction()
 | 
			
		||||
							
								
								
									
										70
									
								
								CMakeModules/ExtendedVersion.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								CMakeModules/ExtendedVersion.cmake
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,70 @@
 | 
			
		||||
# === This file is part of Calamares - <https://calamares.io> ===
 | 
			
		||||
#
 | 
			
		||||
#   SPDX-FileCopyrightText: 2014 Teo Mrnjavac <teo@kde.org>
 | 
			
		||||
#   SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
 | 
			
		||||
#   SPDX-License-Identifier: BSD-2-Clause
 | 
			
		||||
#
 | 
			
		||||
###
 | 
			
		||||
#
 | 
			
		||||
# This file defines one function for extending a VERSION-like value
 | 
			
		||||
# with date and git information (if desired).
 | 
			
		||||
#
 | 
			
		||||
# - extend_version( version-string short_only short_var long_var )
 | 
			
		||||
#   Calling this function will copy *version-string* (which would typically
 | 
			
		||||
#   be a semver-style string, like "3.2.40") into the variable *short_var*.
 | 
			
		||||
#   If *short_only* is true, then:
 | 
			
		||||
#       - the short version is also copied into the variable *long_var*,
 | 
			
		||||
#   If *short_only* is false, then:
 | 
			
		||||
#       - the *version-string* plus date and git information, is copied
 | 
			
		||||
#         into the varialbe *long_var*, in the format {version}-{date}-{hash}
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
function( get_git_version_info out_var )
 | 
			
		||||
    set(CMAKE_VERSION_SOURCE "")
 | 
			
		||||
    if(EXISTS ${CMAKE_SOURCE_DIR}/.git/HEAD)
 | 
			
		||||
        find_program(GIT_EXECUTABLE NAMES git git.cmd)
 | 
			
		||||
        mark_as_advanced(GIT_EXECUTABLE)
 | 
			
		||||
        if(GIT_EXECUTABLE)
 | 
			
		||||
            execute_process(
 | 
			
		||||
                COMMAND ${GIT_EXECUTABLE} rev-parse --verify -q --short=8 HEAD
 | 
			
		||||
                OUTPUT_VARIABLE head
 | 
			
		||||
                OUTPUT_STRIP_TRAILING_WHITESPACE
 | 
			
		||||
                WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
 | 
			
		||||
            )
 | 
			
		||||
            if(head)
 | 
			
		||||
                set(CMAKE_VERSION_SOURCE "${head}")
 | 
			
		||||
                execute_process(
 | 
			
		||||
                    COMMAND ${GIT_EXECUTABLE} update-index -q --refresh
 | 
			
		||||
                    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
 | 
			
		||||
                )
 | 
			
		||||
                execute_process(
 | 
			
		||||
                    COMMAND ${GIT_EXECUTABLE} diff-index --name-only HEAD --
 | 
			
		||||
                    OUTPUT_VARIABLE dirty
 | 
			
		||||
                    OUTPUT_STRIP_TRAILING_WHITESPACE
 | 
			
		||||
                    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
 | 
			
		||||
                )
 | 
			
		||||
                if(dirty)
 | 
			
		||||
                    set(CMAKE_VERSION_SOURCE "${CMAKE_VERSION_SOURCE}-dirty")
 | 
			
		||||
                endif()
 | 
			
		||||
            endif()
 | 
			
		||||
        endif()
 | 
			
		||||
    endif()
 | 
			
		||||
    set( ${out_var} "${CMAKE_VERSION_SOURCE}" PARENT_SCOPE )
 | 
			
		||||
endfunction()
 | 
			
		||||
 | 
			
		||||
function( extend_version version short_only short_var long_var )
 | 
			
		||||
    set( ${short_var} "${version}" PARENT_SCOPE )
 | 
			
		||||
    set( _v "${version}" )
 | 
			
		||||
    if ( NOT short_only )
 | 
			
		||||
        string( TIMESTAMP CALAMARES_VERSION_DATE "%Y%m%d" )
 | 
			
		||||
        if( CALAMARES_VERSION_DATE GREATER 0 )
 | 
			
		||||
            set( _v ${_v}.${CALAMARES_VERSION_DATE} )
 | 
			
		||||
        endif()
 | 
			
		||||
        get_git_version_info( _gitv )
 | 
			
		||||
        if( _gitv )
 | 
			
		||||
            set( _v "${_v}-${_gitv}" )
 | 
			
		||||
        endif()
 | 
			
		||||
    endif()
 | 
			
		||||
    set( ${long_var} "${_v}" PARENT_SCOPE )
 | 
			
		||||
endfunction()
 | 
			
		||||
@@ -1,185 +0,0 @@
 | 
			
		||||
# === This file is part of Calamares - <https://calamares.io> ===
 | 
			
		||||
#
 | 
			
		||||
#   SPDX-FileCopyrightText: 2016 Teo Mrnjavac <teo@kde.org>
 | 
			
		||||
#   SPDX-FileCopyrightText: 2017 Adriaan de Groot <groot@kde.org>
 | 
			
		||||
#   SPDX-License-Identifier: BSD-2-Clause
 | 
			
		||||
#
 | 
			
		||||
###
 | 
			
		||||
#
 | 
			
		||||
# Find PythonQt
 | 
			
		||||
#
 | 
			
		||||
# Sets PYTHONQT_FOUND, PYTHONQT_INCLUDE_DIR, PYTHONQT_LIBRARY, PYTHONQT_LIBRARIES
 | 
			
		||||
#
 | 
			
		||||
# Also sets PYTHONQT_INCLUDE_DIRS to add whatever directories
 | 
			
		||||
#   that are needed for extensions.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
# Python is required
 | 
			
		||||
find_package(PythonLibs)
 | 
			
		||||
if(NOT PYTHONLIBS_FOUND)
 | 
			
		||||
  message(FATAL_ERROR "error: Python is required to build PythonQt")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
# Cut X.Y[.Z] down to just X.Y
 | 
			
		||||
string(REGEX REPLACE
 | 
			
		||||
    "^([0-9][0-9]*)\.([0-9][0-9]*)"
 | 
			
		||||
    "\\1.\\2@"
 | 
			
		||||
    _PYTHONLIBS_MAJMIN
 | 
			
		||||
    ${PYTHONLIBS_VERSION_STRING}
 | 
			
		||||
)
 | 
			
		||||
string(REGEX REPLACE
 | 
			
		||||
    "@.*"
 | 
			
		||||
    ""
 | 
			
		||||
    PYTHONLIBS_MAJMIN
 | 
			
		||||
    ${_PYTHONLIBS_MAJMIN}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
if(NOT EXISTS "${PYTHONQT_INSTALL_DIR}")
 | 
			
		||||
    find_path(PYTHONQT_INSTALL_DIR
 | 
			
		||||
        NAMES
 | 
			
		||||
            include/PythonQt/PythonQt.h
 | 
			
		||||
            include/PythonQt5/PythonQt.h
 | 
			
		||||
        DOC "Directory where PythonQt was installed.")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
# XXX Since PythonQt 3.0 is not yet cmakeified, depending
 | 
			
		||||
#     on how PythonQt is built, headers will not always be
 | 
			
		||||
#     installed in "include/PythonQt". That is why "src"
 | 
			
		||||
#     is added as an option. See [1] for more details.
 | 
			
		||||
#     [1] https://github.com/commontk/CTK/pull/538#issuecomment-86106367
 | 
			
		||||
find_path(PYTHONQT_INCLUDE_DIR PythonQt.h
 | 
			
		||||
    PATHS
 | 
			
		||||
        "${PYTHONQT_INSTALL_DIR}/include/PythonQt"
 | 
			
		||||
        "${PYTHONQT_INSTALL_DIR}/include/PythonQt5"
 | 
			
		||||
        "${PYTHONQT_INSTALL_DIR}/src"
 | 
			
		||||
    DOC "Path to the PythonQt include directory")
 | 
			
		||||
find_path(PYTHONQT_ALL_INCLUDE_DIR PythonQt_QtAll.h
 | 
			
		||||
    PATHS
 | 
			
		||||
        "${PYTHONQT_INCLUDE_DIR}"
 | 
			
		||||
        "${PYTHONQT_INSTALL_DIR}"
 | 
			
		||||
    PATH_SUFFIXES
 | 
			
		||||
        "extensions/PythonQt_QtAll"
 | 
			
		||||
        "src"
 | 
			
		||||
    DOC "Path to the PythonQt 'all' header")
 | 
			
		||||
 | 
			
		||||
if ( NOT PythonQt_FIND_QUIETLY )
 | 
			
		||||
    message( STATUS "Searching for PythonQt (PythonLibs ${PYTHONLIBS_MAJMIN}) .." )
 | 
			
		||||
    if ( PYTHONQT_INCLUDE_DIR )
 | 
			
		||||
        message( STATUS "  .. found include ${PYTHONQT_INCLUDE_DIR}" )
 | 
			
		||||
        message( STATUS "  .. found all include ${PYTHONQT_ALL_INCLUDE_DIR}" )
 | 
			
		||||
    endif()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
# Minimum v3.1 is needed
 | 
			
		||||
find_library(PYTHONQT_LIBRARY_RELEASE
 | 
			
		||||
    NAMES
 | 
			
		||||
        PythonQt-Qt5-Python${PYTHONLIBS_MAJMIN}
 | 
			
		||||
        PythonQt-Qt5-Python3
 | 
			
		||||
        PythonQt
 | 
			
		||||
    PATHS "${PYTHONQT_INSTALL_DIR}/lib"
 | 
			
		||||
    DOC "The PythonQt library."
 | 
			
		||||
)
 | 
			
		||||
find_library(PYTHONQT_LIBRARY_DEBUG
 | 
			
		||||
    NAMES
 | 
			
		||||
        PythonQt-Qt5-Python${PYTHONLIBS_MAJMIN}JMIN${CTK_CMAKE_DEBUG_POSTFIX}
 | 
			
		||||
        PythonQt-Qt5-Python${PYTHONLIBS_MAJMIN}${CMAKE_DEBUG_POSTFIX}
 | 
			
		||||
        PythonQt-Qt5-Python${PYTHONLIBS_MAJMIN}
 | 
			
		||||
        PythonQt-Qt5-Python3${CTK_CMAKE_DEBUG_POSTFIX}
 | 
			
		||||
        PythonQt-Qt5-Python3${CMAKE_DEBUG_POSTFIX}
 | 
			
		||||
        PythonQt-Qt5-Python3
 | 
			
		||||
        PythonQt${CTK_CMAKE_DEBUG_POSTFIX}
 | 
			
		||||
        PythonQt${CMAKE_DEBUG_POSTFIX}
 | 
			
		||||
        PythonQt
 | 
			
		||||
    PATHS "${PYTHONQT_INSTALL_DIR}/lib"
 | 
			
		||||
    DOC "The PythonQt library (debug build)."
 | 
			
		||||
)
 | 
			
		||||
find_library(PYTHONQT_QTALL_LIBRARY_RELEASE
 | 
			
		||||
    NAMES
 | 
			
		||||
        PythonQt_QtAll-Qt5-Python${PYTHONLIBS_MAJMIN}
 | 
			
		||||
        PythonQt_QtAll-Qt5-Python3
 | 
			
		||||
        PythonQt_QtAll
 | 
			
		||||
    PATHS "${PYTHONQT_INSTALL_DIR}/lib"
 | 
			
		||||
    DOC "Full Qt bindings for the PythonQt library."
 | 
			
		||||
)
 | 
			
		||||
find_library(PYTHONQT_QTALL_LIBRARY_DEBUG
 | 
			
		||||
    NAMES
 | 
			
		||||
        PythonQt_QtAll-Qt5-Python${PYTHONLIBS_MAJMIN}${CTK_CMAKE_DEBUG_POSTFIX}
 | 
			
		||||
        PythonQt_QtAll-Qt5-Python${PYTHONLIBS_MAJMIN}${CMAKE_DEBUG_POSTFIX}
 | 
			
		||||
        PythonQt_QtAll-Qt5-Python${PYTHONLIBS_MAJMIN}
 | 
			
		||||
        PythonQt_QtAll-Qt5-Python3${CTK_CMAKE_DEBUG_POSTFIX}
 | 
			
		||||
        PythonQt_QtAll-Qt5-Python3${CMAKE_DEBUG_POSTFIX}
 | 
			
		||||
        PythonQt_QtAll-Qt5-Python3
 | 
			
		||||
        PythonQt_QtAll${CTK_CMAKE_DEBUG_POSTFIX}
 | 
			
		||||
        PythonQt_QtAll${CMAKE_DEBUG_POSTFIX}
 | 
			
		||||
        PythonQt_QtAll
 | 
			
		||||
    PATHS "${PYTHONQT_INSTALL_DIR}/lib"
 | 
			
		||||
    DOC "Full Qt bindings for the PythonQt library (debug build)."
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
set(PYTHONQT_LIBRARY)
 | 
			
		||||
if(PYTHONQT_LIBRARY_RELEASE)
 | 
			
		||||
  list(APPEND PYTHONQT_LIBRARY optimized ${PYTHONQT_LIBRARY_RELEASE})
 | 
			
		||||
endif()
 | 
			
		||||
if(PYTHONQT_LIBRARY_DEBUG)
 | 
			
		||||
  list(APPEND PYTHONQT_LIBRARY debug ${PYTHONQT_LIBRARY_DEBUG})
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
set(PYTHONQT_QTALL_LIBRARY)
 | 
			
		||||
if(PYTHONQT_QTALL_LIBRARY_RELEASE)
 | 
			
		||||
  list(APPEND PYTHONQT_QTALL_LIBRARY optimized ${PYTHONQT_QTALL_LIBRARY_RELEASE})
 | 
			
		||||
endif()
 | 
			
		||||
if(PYTHONQT_QTALL_LIBRARY_DEBUG)
 | 
			
		||||
  list(APPEND PYTHONQT_QTALL_LIBRARY debug ${PYTHONQT_QTALL_LIBRARY_DEBUG})
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if ( NOT PythonQt_FIND_QUIETLY )
 | 
			
		||||
    if ( PYTHONQT_LIBRARY )
 | 
			
		||||
        message( STATUS "  .. found library ${PYTHONQT_LIBRARY}" )
 | 
			
		||||
    endif()
 | 
			
		||||
    if ( PYTHONQT_QTALL_LIBRARY )
 | 
			
		||||
        message( STATUS "  .. found qtall   ${PYTHONQT_QTALL_LIBRARY}" )
 | 
			
		||||
    endif()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
mark_as_advanced(PYTHONQT_INSTALL_DIR)
 | 
			
		||||
mark_as_advanced(PYTHONQT_INCLUDE_DIR)
 | 
			
		||||
mark_as_advanced(PYTHONQT_LIBRARY_RELEASE)
 | 
			
		||||
mark_as_advanced(PYTHONQT_LIBRARY_DEBUG)
 | 
			
		||||
mark_as_advanced(PYTHONQT_QTALL_LIBRARY_RELEASE)
 | 
			
		||||
mark_as_advanced(PYTHONQT_QTALL_LIBRARY_DEBUG)
 | 
			
		||||
 | 
			
		||||
# On linux, also find libutil
 | 
			
		||||
if(UNIX AND NOT APPLE)
 | 
			
		||||
  find_library(PYTHONQT_LIBUTIL util)
 | 
			
		||||
  mark_as_advanced(PYTHONQT_LIBUTIL)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
# All upper case _FOUND variable is maintained for backwards compatibility.
 | 
			
		||||
set(PYTHONQT_FOUND 0)
 | 
			
		||||
set(PythonQt_FOUND 0)
 | 
			
		||||
 | 
			
		||||
if(PYTHONQT_INCLUDE_DIR AND PYTHONQT_LIBRARY AND PYTHONQT_QTALL_LIBRARY)
 | 
			
		||||
  # Currently CMake'ified PythonQt only supports building against a python Release build.
 | 
			
		||||
  # This applies independently of CTK build type (Release, Debug, ...)
 | 
			
		||||
  add_definitions(-DPYTHONQT_USE_RELEASE_PYTHON_FALLBACK)
 | 
			
		||||
  set(PYTHONQT_FOUND 1)
 | 
			
		||||
  set(PythonQt_FOUND ${PYTHONQT_FOUND})
 | 
			
		||||
  set(PYTHONQT_LIBRARIES ${PYTHONQT_LIBRARY} ${PYTHONQT_LIBUTIL} ${PYTHONQT_QTALL_LIBRARY})
 | 
			
		||||
  set(PYTHONQT_INCLUDE_DIRS ${PYTHONQT_INCLUDE_DIR})
 | 
			
		||||
  if(PYTHONQT_ALL_INCLUDE_DIR)
 | 
			
		||||
    list(APPEND PYTHONQT_INCLUDE_DIRS ${PYTHONQT_ALL_INCLUDE_DIR})
 | 
			
		||||
  endif()
 | 
			
		||||
elseif(NOT PythonQt_FIND_QUIETLY)
 | 
			
		||||
  set(_missing "")
 | 
			
		||||
  if (NOT PYTHONQT_INCLUDE_DIR)
 | 
			
		||||
    list(APPEND _missing "includes")
 | 
			
		||||
  endif()
 | 
			
		||||
  if (NOT PYTHONQT_LIBRARY)
 | 
			
		||||
    list(APPEND _missing "library")
 | 
			
		||||
  endif()
 | 
			
		||||
  if (NOT PYTHONQT_QTALL_LIBRARY)
 | 
			
		||||
    list(APPEND _missing "qtall")
 | 
			
		||||
  endif()
 | 
			
		||||
  message(STATUS "PythonQt not found, missing components ${_missing}")
 | 
			
		||||
endif()
 | 
			
		||||
@@ -13,7 +13,7 @@
 | 
			
		||||
#   YAMLCPP_LIBRARY, where to find yaml-cpp
 | 
			
		||||
#   YAMLCPP_INCLUDE_DIR, where to find yaml.h
 | 
			
		||||
# There is also one IMPORTED library target,
 | 
			
		||||
#   yamlcpp
 | 
			
		||||
#   yamlcpp::yamlcpp
 | 
			
		||||
#
 | 
			
		||||
# By default, the dynamic libraries of yaml-cpp will be found. To find the static ones instead,
 | 
			
		||||
# you must set the YAMLCPP_STATIC_LIBRARY variable to TRUE before calling find_package(YamlCpp ...).
 | 
			
		||||
@@ -21,6 +21,10 @@
 | 
			
		||||
# If yaml-cpp is not installed in a standard path, you can use the YAMLCPP_DIR CMake variable
 | 
			
		||||
# to tell CMake where yaml-cpp is.
 | 
			
		||||
 | 
			
		||||
if(TARGET yamlcpp::yamlcpp)
 | 
			
		||||
    return()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
# attempt to find static library first if this is set
 | 
			
		||||
if(YAMLCPP_STATIC_LIBRARY)
 | 
			
		||||
    set(YAMLCPP_STATIC libyaml-cpp.a)
 | 
			
		||||
@@ -61,9 +65,9 @@ mark_as_advanced(YAMLCPP_INCLUDE_DIR YAMLCPP_LIBRARY)
 | 
			
		||||
 | 
			
		||||
# Add an imported target
 | 
			
		||||
if( YAMLCPP_LIBRARY )
 | 
			
		||||
    add_library( yamlcpp UNKNOWN IMPORTED )
 | 
			
		||||
    set_property( TARGET yamlcpp PROPERTY IMPORTED_LOCATION ${YAMLCPP_LIBRARY} )
 | 
			
		||||
    add_library( yamlcpp::yamlcpp UNKNOWN IMPORTED )
 | 
			
		||||
    set_property( TARGET yamlcpp::yamlcpp PROPERTY IMPORTED_LOCATION ${YAMLCPP_LIBRARY} )
 | 
			
		||||
    if ( YAMLCPP_INCLUDE_DIR )
 | 
			
		||||
        set_property( TARGET yamlcpp PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${YAMLCPP_INCLUDE_DIR} )
 | 
			
		||||
        set_property( TARGET yamlcpp::yamlcpp PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${YAMLCPP_INCLUDE_DIR} )
 | 
			
		||||
    endif()
 | 
			
		||||
endif()
 | 
			
		||||
 
 | 
			
		||||
@@ -7,33 +7,57 @@
 | 
			
		||||
#
 | 
			
		||||
# Finds KPMcore and consistently sets API flags based on the version.
 | 
			
		||||
#
 | 
			
		||||
if ( NOT KPMcore_searched_for )
 | 
			
		||||
    set( KPMcore_searched_for TRUE )
 | 
			
		||||
# If KPMcore is not found, still create calamares::kpmcore interface
 | 
			
		||||
# library, which will add definition WITHOUT_KPMcore.
 | 
			
		||||
#
 | 
			
		||||
if(NOT TARGET calapmcore)
 | 
			
		||||
    find_package(${kfname}Config CONFIG)
 | 
			
		||||
    find_package(${kfname}I18n CONFIG)
 | 
			
		||||
    find_package(${kfname}WidgetsAddons CONFIG)
 | 
			
		||||
 | 
			
		||||
    find_package( KPMcore 3.3 )
 | 
			
		||||
    if( WITH_QT6)
 | 
			
		||||
        find_package(KPMcore 24.01.75)
 | 
			
		||||
    else()
 | 
			
		||||
        find_package(KPMcore 20.04.0)
 | 
			
		||||
    endif()
 | 
			
		||||
    set_package_properties(
 | 
			
		||||
        KPMcore PROPERTIES
 | 
			
		||||
        KPMcore
 | 
			
		||||
        PROPERTIES
 | 
			
		||||
        URL "https://invent.kde.org/kde/kpmcore"
 | 
			
		||||
        DESCRIPTION "KDE Partitioning library"
 | 
			
		||||
        TYPE RECOMMENDED
 | 
			
		||||
        PURPOSE "For disk partitioning support"
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    if( KPMcore_FOUND )
 | 
			
		||||
        set( KPMcore_API_DEFINITIONS "" )
 | 
			
		||||
        if( KPMcore_VERSION VERSION_GREATER "3.3.70" AND KPMcore_VERSION VERSION_LESS "4.0" )
 | 
			
		||||
            message( FATAL_ERROR "KPMCore beta versions ${KPMcore_VERSION} not supported" )
 | 
			
		||||
        endif()
 | 
			
		||||
        if ( KPMcore_VERSION VERSION_GREATER "3.3.0")
 | 
			
		||||
            list( APPEND KPMcore_API_DEFINITIONS WITH_KPMCORE331API) # kpmcore > 3.3.0 with deprecations
 | 
			
		||||
        endif()
 | 
			
		||||
        if ( KPMcore_VERSION VERSION_GREATER_EQUAL "4.0")
 | 
			
		||||
            list( APPEND KPMcore_API_DEFINITIONS WITH_KPMCORE4API) # kpmcore 4 with new API
 | 
			
		||||
        endif()
 | 
			
		||||
        if( KPMcore_VERSION VERSION_GREATER_EQUAL "4.2" )
 | 
			
		||||
            list( APPEND KPMcore_API_DEFINITIONS WITH_KPMCORE42API) # kpmcore 4.2 with new API
 | 
			
		||||
        endif()
 | 
			
		||||
    # Create an internal Calamares interface to KPMcore
 | 
			
		||||
    # and give it a nice alias name. If kpmcore is not found,
 | 
			
		||||
    # then make a "no KPMcore" library.
 | 
			
		||||
    add_library(calapmcore INTERFACE)
 | 
			
		||||
 | 
			
		||||
    if(KPMcore_FOUND)
 | 
			
		||||
        find_package(${qtname} REQUIRED DBus) # Needed for KPMCore
 | 
			
		||||
        find_package(${kfname} REQUIRED I18n WidgetsAddons) # Needed for KPMCore
 | 
			
		||||
 | 
			
		||||
        target_link_libraries(calapmcore INTERFACE kpmcore ${qtname}::DBus ${kfname}::I18n ${kfname}::WidgetsAddons)
 | 
			
		||||
        target_include_directories(calapmcore INTERFACE ${KPMCORE_INCLUDE_DIR})
 | 
			
		||||
        # If there were KPMcore API variations, figure them out here
 | 
			
		||||
        # target_compile_definitions(calapmcore INTERFACE WITH_KPMcore)
 | 
			
		||||
 | 
			
		||||
        # Flag that this library has KPMcore support. A variable
 | 
			
		||||
        # set here has the wrong scope. ENV{} would be visible
 | 
			
		||||
        # everywhere but seems the wrong thing to do. Setting
 | 
			
		||||
        # properties on calapmcore requires a newer CMake than
 | 
			
		||||
        # Debian 11 has, so runs into support issues.
 | 
			
		||||
        add_library(calamares::kpmcore ALIAS calapmcore)
 | 
			
		||||
    else()
 | 
			
		||||
        set( KPMcore_API_DEFINITIONS WITHOUT_KPMcore )
 | 
			
		||||
        target_compile_definitions(calapmcore INTERFACE WITHOUT_KPMcore)
 | 
			
		||||
    endif()
 | 
			
		||||
else()
 | 
			
		||||
    if(TARGET calamares::kpmcore)
 | 
			
		||||
        message(STATUS "KPMcore has already been found")
 | 
			
		||||
        set(KPMcore_FOUND TRUE)
 | 
			
		||||
    else()
 | 
			
		||||
        message(STATUS "KPMcore has been searched-for and not found")
 | 
			
		||||
        set(KPMcore_FOUND FALSE)
 | 
			
		||||
    endif()
 | 
			
		||||
endif()
 | 
			
		||||
 
 | 
			
		||||
@@ -28,14 +28,18 @@ rules of decent behavior in both communities are pretty much the same).
 | 
			
		||||
 | 
			
		||||
GitHub Issues are **one** place for discussing Calamares if there are concrete
 | 
			
		||||
problems or a new feature to discuss.
 | 
			
		||||
Issues are not a help channel.
 | 
			
		||||
Visit Matrix for help with configuration or compilation.
 | 
			
		||||
 | 
			
		||||
Regular Calamares development chit-chat happens on old-school IRC
 | 
			
		||||
(no registration required). Responsiveness is best during the day
 | 
			
		||||
in Europe, but feel free to idle. **DO NOT** ask-and-leave. Keep
 | 
			
		||||
that chat window open because it can easily take a few hours for
 | 
			
		||||
someone to notice a message.
 | 
			
		||||
Regular Calamares development chit-chat happens in a [Matrix](https://matrix.org/)
 | 
			
		||||
room, `#calamares:kde.org`. Responsiveness is best during the day
 | 
			
		||||
in Europe, but feel free to idle.
 | 
			
		||||
Matrix is persistent, and we'll see your message eventually.
 | 
			
		||||
 | 
			
		||||
[](https://webchat.freenode.net/?channel=#calamares?nick=guest)
 | 
			
		||||
**Note:** You need an account to access Matrix. It doesn't have to be a KDE account,
 | 
			
		||||
it can be on any Matrix homeserver.
 | 
			
		||||
 | 
			
		||||
* [](https://webchat.kde.org/#/room/%23calamares:kde.org)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## General Guidelines
 | 
			
		||||
@@ -53,7 +57,7 @@ stay that way.
 | 
			
		||||
 | 
			
		||||
If you are writing documentation, use *en_US* spelling.
 | 
			
		||||
 | 
			
		||||
If you are doing cool stuff, let us know (on IRC or through issues).
 | 
			
		||||
If you are doing cool stuff, let us know (on Matrix or through issues).
 | 
			
		||||
 | 
			
		||||
**Do** fork Calamares to try new things, **don't** keep your fork to
 | 
			
		||||
yourself, **do** upstream things as much as you can. When you make cool
 | 
			
		||||
@@ -70,26 +74,71 @@ Up to date
 | 
			
		||||
[building-Calamares](https://github.com/calamares/calamares/wiki/Develop-Guide)
 | 
			
		||||
instructions are on the wiki.
 | 
			
		||||
 | 
			
		||||
### Dependencies
 | 
			
		||||
### Simple Build in Docker
 | 
			
		||||
 | 
			
		||||
You may have success with the Docker images that the CI system uses.
 | 
			
		||||
Pick one (or more) of these images which are also used in CI:
 | 
			
		||||
- `docker pull docker://opensuse/tumbleweed`
 | 
			
		||||
- `docker pull kdeneon/plasma:user`
 | 
			
		||||
- `docker pull fedora:38`
 | 
			
		||||
 | 
			
		||||
Then start a container with the right image, from the root of Calamares
 | 
			
		||||
source checkout. Start with this command and substitute `opensuse/tumbleweed`
 | 
			
		||||
or `kdeneon/plasma:user` for the `$IMAGE` part.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
docker run -ti \
 | 
			
		||||
    --tmpfs /build:rw,exec \
 | 
			
		||||
    --user 0:0 \
 | 
			
		||||
    -e DISPLAY=:0 \
 | 
			
		||||
    -v /tmp/.X11-unix:/tmp/.X11-unix \
 | 
			
		||||
    -v .:/src \
 | 
			
		||||
    $IMAGE \
 | 
			
		||||
    bash
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This starts a container with the chosen image with a temporary build
 | 
			
		||||
directory in `/build` and the Calamaressources mounted as `/src`.
 | 
			
		||||
 | 
			
		||||
Run the script to install dependencies: you could use `deploycala.py`
 | 
			
		||||
or one of the shell scripts in `ci/` to install the right
 | 
			
		||||
dependencies for the image (in this example, for openSUSE and Qt6).
 | 
			
		||||
- `cd /src`
 | 
			
		||||
- `./ci/deps-opensuse-qt6.sh`
 | 
			
		||||
 | 
			
		||||
Then run CMake (add any CMake options you like at the end) and ninja.
 | 
			
		||||
There is a script `ci/build.sh` that does this, too (without options).
 | 
			
		||||
- `cmake -S /src -B /build -G Ninja`
 | 
			
		||||
- `ninja -C /build`
 | 
			
		||||
 | 
			
		||||
To run Calamares inside the container, or e.g. `loadmodule` to test
 | 
			
		||||
individual modules, you may need to configure X authentication; a
 | 
			
		||||
simple and insecure way of doing that is to run `xhost +` in the host
 | 
			
		||||
environment of the Docker containers.
 | 
			
		||||
 | 
			
		||||
### Dependencies for Calamares 3.3
 | 
			
		||||
 | 
			
		||||
> The dependencies for Calamares 3.3 reflect "resonably current"
 | 
			
		||||
> software as of September 2023. For Calamares 3.2 dependencies,
 | 
			
		||||
> which are 2017-era, see the `CONTRIBUTING` file in that branch.
 | 
			
		||||
 | 
			
		||||
Main:
 | 
			
		||||
* Compiler with C++17 support: GCC >= 7 or Clang >= 5
 | 
			
		||||
* CMake >= 3.3
 | 
			
		||||
* Qt >= 5.9
 | 
			
		||||
* Compiler with C++17 support
 | 
			
		||||
* CMake >= 3.16
 | 
			
		||||
* yaml-cpp >= 0.5.1
 | 
			
		||||
* Python >= 3.3 (required for some modules)
 | 
			
		||||
* Boost.Python >= 1.55.0 (required for some modules)
 | 
			
		||||
* KDE extra-cmake-modules >= 5.18 (recommended; required for some modules;
 | 
			
		||||
* Qt >= 5.15 or Qt >= 6.5
 | 
			
		||||
* KDE Frameworks KCoreAddons >= 5.78
 | 
			
		||||
* KDE extra-cmake-modules >= 5.78 (recommended; required for some modules;
 | 
			
		||||
  required for some tests)
 | 
			
		||||
* KDE Frameworks KCoreAddons (>= 5.58 recommended)
 | 
			
		||||
* PythonQt (optional, deprecated)
 | 
			
		||||
* Python >= 3.6 (required for some modules)
 | 
			
		||||
* Boost.Python >= 1.72.0 (required for some modules if WITH_PYBIND11 is OFF)
 | 
			
		||||
 | 
			
		||||
Individual modules may have their own requirements;
 | 
			
		||||
these are listed in CMake output.
 | 
			
		||||
Particular requirements (not complete):
 | 
			
		||||
 | 
			
		||||
* *fsresizer* KPMCore >= 3.3 (>= 4.2 recommended)
 | 
			
		||||
* *partition* KPMCore >= 3.3 (>= 4.2 recommended)
 | 
			
		||||
* *fsresizer* KPMCore >= 20.04
 | 
			
		||||
* *partition* KPMCore >= 20.04
 | 
			
		||||
* *users* LibPWQuality (optional)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -23,6 +23,12 @@
 | 
			
		||||
#
 | 
			
		||||
include(${CMAKE_CURRENT_LIST_DIR}/CalamaresConfigVersion.cmake)
 | 
			
		||||
include(${CMAKE_CURRENT_LIST_DIR}/CalamaresTargets.cmake)
 | 
			
		||||
if (NOT TARGET Calamares::calamares OR NOT TARGET Calamares::calamaresui)
 | 
			
		||||
    message(FATAL_ERROR "Calamares found with missing CMake targets")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
# Need various CMake files that are installed alongside this one.
 | 
			
		||||
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
 | 
			
		||||
 | 
			
		||||
### Dependencies
 | 
			
		||||
#
 | 
			
		||||
@@ -40,23 +46,32 @@ macro(accumulate_deps outvar target namespace)
 | 
			
		||||
    endforeach()
 | 
			
		||||
endmacro()
 | 
			
		||||
 | 
			
		||||
# Qt5 infrastructure for translations is required
 | 
			
		||||
set(qt5_required Core Widgets LinguistTools)
 | 
			
		||||
accumulate_deps(qt5_required Calamares::calamares Qt5::)
 | 
			
		||||
accumulate_deps(qt5_required Calamares::calamaresui Qt5::)
 | 
			
		||||
find_package(Qt5 CONFIG REQUIRED ${qt5_required})
 | 
			
		||||
set(Calamares_WITH_QT6 @WITH_QT6@)
 | 
			
		||||
if(Calamares_WITH_QT6)
 | 
			
		||||
    set(qtname "Qt6")
 | 
			
		||||
else()
 | 
			
		||||
    set(qtname "Qt5")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
# Qt infrastructure for translations is required
 | 
			
		||||
set(qt_required Core Widgets LinguistTools)
 | 
			
		||||
accumulate_deps(qt_required Calamares::calamares ${qtname}::)
 | 
			
		||||
accumulate_deps(qt_required Calamares::calamaresui ${qtname}::)
 | 
			
		||||
find_package(${qtname} CONFIG REQUIRED ${qt_required})
 | 
			
		||||
 | 
			
		||||
set(kf5_required "")
 | 
			
		||||
accumulate_deps(kf5_required Calamares::calamares KF5::)
 | 
			
		||||
accumulate_deps(kf5_required Calamares::calamaresui KF5::)
 | 
			
		||||
accumulate_deps(kf5_required Calamares::calamares ${kfname}::)
 | 
			
		||||
accumulate_deps(kf5_required Calamares::calamaresui ${kfname}::)
 | 
			
		||||
if(kf5_required)
 | 
			
		||||
    find_package(ECM ${ECM_VERSION} NO_MODULE)
 | 
			
		||||
    if( ECM_FOUND )
 | 
			
		||||
        list(PREPEND CMAKE_MODULE_PATH ${ECM_MODULE_PATH})
 | 
			
		||||
        find_package(KF5 REQUIRED COMPONENTS ${kf5_required})
 | 
			
		||||
        list(INSERT CMAKE_MODULE_PATH 0 ${ECM_MODULE_PATH})
 | 
			
		||||
        find_package(${kfname} REQUIRED COMPONENTS ${kf5_required})
 | 
			
		||||
    endif()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
find_package(YAMLCPP REQUIRED)
 | 
			
		||||
 | 
			
		||||
### Legacy support
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
@@ -67,8 +82,6 @@ set(Calamares_LIBRARIES Calamares::calamares)
 | 
			
		||||
### CMake support
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
 | 
			
		||||
 | 
			
		||||
include(CalamaresAddBrandingSubdirectory)
 | 
			
		||||
include(CalamaresAddLibrary)
 | 
			
		||||
include(CalamaresAddModuleSubdirectory)
 | 
			
		||||
@@ -81,5 +94,4 @@ include(CalamaresAddPlugin)
 | 
			
		||||
# This list should match the one in libcalamares/CalamaresConfig.h,
 | 
			
		||||
# which is the C++-language side of the same configuration.
 | 
			
		||||
set(Calamares_WITH_PYTHON @WITH_PYTHON@)
 | 
			
		||||
set(Calamares_WITH_PYTHONQT @WITH_PYTHONQT@)
 | 
			
		||||
set(Calamares_WITH_QML @WITH_QML@)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
#   SPDX-FileCopyrightText: 2017 Rohan Garg <rohan@garg.io>
 | 
			
		||||
#   SPDX-License-Identifier: BSD-2-Clause
 | 
			
		||||
 | 
			
		||||
FROM kdeneon/all:user
 | 
			
		||||
RUN sudo apt-get update && sudo apt-get -y install build-essential cmake extra-cmake-modules gettext kio-dev libatasmart-dev libboost-python-dev libkf5config-dev libkf5coreaddons-dev libkf5i18n-dev libkf5iconthemes-dev libkf5parts-dev libkf5service-dev libkf5solid-dev libkpmcore-dev libparted-dev libpolkit-qt5-1-dev libqt5svg5-dev libqt5webkit5-dev libyaml-cpp-dev os-prober pkg-config python3-dev qtbase5-dev qtdeclarative5-dev qttools5-dev qttools5-dev-tools
 | 
			
		||||
@@ -1,488 +0,0 @@
 | 
			
		||||
 | 
			
		||||
 The KD Tools Library is Copyright (C) 2001-2010 Klaralvdalens Datakonsult AB.
 | 
			
		||||
 | 
			
		||||
 You may use, distribute and copy the KD Tools Library under the terms of
 | 
			
		||||
 GNU Library General Public License version 2, which is displayed below.
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------------
 | 
			
		||||
                  GNU LIBRARY GENERAL PUBLIC LICENSE
 | 
			
		||||
                       Version 2, June 1991
 | 
			
		||||
 | 
			
		||||
 Copyright (C) 1991 Free Software Foundation, Inc.
 | 
			
		||||
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
 Everyone is permitted to copy and distribute verbatim copies
 | 
			
		||||
 of this license document, but changing it is not allowed.
 | 
			
		||||
 | 
			
		||||
[This is the first released version of the library GPL.  It is
 | 
			
		||||
 numbered 2 because it goes with version 2 of the ordinary GPL.]
 | 
			
		||||
 | 
			
		||||
                            Preamble
 | 
			
		||||
 | 
			
		||||
  The licenses for most software are designed to take away your
 | 
			
		||||
freedom to share and change it.  By contrast, the GNU General Public
 | 
			
		||||
Licenses are intended to guarantee your freedom to share and change
 | 
			
		||||
free software--to make sure the software is free for all its users.
 | 
			
		||||
 | 
			
		||||
  This license, the Library General Public License, applies to some
 | 
			
		||||
specially designated Free Software Foundation software, and to any
 | 
			
		||||
other libraries whose authors decide to use it.  You can use it for
 | 
			
		||||
your libraries, too.
 | 
			
		||||
 | 
			
		||||
  When we speak of free software, we are referring to freedom, not
 | 
			
		||||
price.  Our General Public Licenses are designed to make sure that you
 | 
			
		||||
have the freedom to distribute copies of free software (and charge for
 | 
			
		||||
this service if you wish), that you receive source code or can get it
 | 
			
		||||
if you want it, that you can change the software or use pieces of it
 | 
			
		||||
in new free programs; and that you know you can do these things.
 | 
			
		||||
 | 
			
		||||
  To protect your rights, we need to make restrictions that forbid
 | 
			
		||||
anyone to deny you these rights or to ask you to surrender the rights.
 | 
			
		||||
These restrictions translate to certain responsibilities for you if
 | 
			
		||||
you distribute copies of the library, or if you modify it.
 | 
			
		||||
 | 
			
		||||
  For example, if you distribute copies of the library, whether gratis
 | 
			
		||||
or for a fee, you must give the recipients all the rights that we gave
 | 
			
		||||
you.  You must make sure that they, too, receive or can get the source
 | 
			
		||||
code.  If you link a program with the library, you must provide
 | 
			
		||||
complete object files to the recipients so that they can relink them
 | 
			
		||||
with the library, after making changes to the library and recompiling
 | 
			
		||||
it.  And you must show them these terms so they know their rights.
 | 
			
		||||
 | 
			
		||||
  Our method of protecting your rights has two steps: (1) copyright
 | 
			
		||||
the library, and (2) offer you this license which gives you legal
 | 
			
		||||
permission to copy, distribute and/or modify the library.
 | 
			
		||||
 | 
			
		||||
  Also, for each distributor's protection, we want to make certain
 | 
			
		||||
that everyone understands that there is no warranty for this free
 | 
			
		||||
library.  If the library is modified by someone else and passed on, we
 | 
			
		||||
want its recipients to know that what they have is not the original
 | 
			
		||||
version, so that any problems introduced by others will not reflect on
 | 
			
		||||
the original authors' reputations.
 | 
			
		||||
 | 
			
		||||
  Finally, any free program is threatened constantly by software
 | 
			
		||||
patents.  We wish to avoid the danger that companies distributing free
 | 
			
		||||
software will individually obtain patent licenses, thus in effect
 | 
			
		||||
transforming the program into proprietary software.  To prevent this,
 | 
			
		||||
we have made it clear that any patent must be licensed for everyone's
 | 
			
		||||
free use or not licensed at all.
 | 
			
		||||
 | 
			
		||||
  Most GNU software, including some libraries, is covered by the ordinary
 | 
			
		||||
GNU General Public License, which was designed for utility programs.  This
 | 
			
		||||
license, the GNU Library General Public License, applies to certain
 | 
			
		||||
designated libraries.  This license is quite different from the ordinary
 | 
			
		||||
one; be sure to read it in full, and don't assume that anything in it is
 | 
			
		||||
the same as in the ordinary license.
 | 
			
		||||
 | 
			
		||||
  The reason we have a separate public license for some libraries is that
 | 
			
		||||
they blur the distinction we usually make between modifying or adding to a
 | 
			
		||||
program and simply using it.  Linking a program with a library, without
 | 
			
		||||
changing the library, is in some sense simply using the library, and is
 | 
			
		||||
analogous to running a utility program or application program.  However, in
 | 
			
		||||
a textual and legal sense, the linked executable is a combined work, a
 | 
			
		||||
derivative of the original library, and the ordinary General Public License
 | 
			
		||||
treats it as such.
 | 
			
		||||
 | 
			
		||||
  Because of this blurred distinction, using the ordinary General
 | 
			
		||||
Public License for libraries did not effectively promote software
 | 
			
		||||
sharing, because most developers did not use the libraries.  We
 | 
			
		||||
concluded that weaker conditions might promote sharing better.
 | 
			
		||||
 | 
			
		||||
  However, unrestricted linking of non-free programs would deprive the
 | 
			
		||||
users of those programs of all benefit from the free status of the
 | 
			
		||||
libraries themselves.  This Library General Public License is intended to
 | 
			
		||||
permit developers of non-free programs to use free libraries, while
 | 
			
		||||
preserving your freedom as a user of such programs to change the free
 | 
			
		||||
libraries that are incorporated in them.  (We have not seen how to achieve
 | 
			
		||||
this as regards changes in header files, but we have achieved it as regards
 | 
			
		||||
changes in the actual functions of the Library.)  The hope is that this
 | 
			
		||||
will lead to faster development of free libraries.
 | 
			
		||||
 | 
			
		||||
  The precise terms and conditions for copying, distribution and
 | 
			
		||||
modification follow.  Pay close attention to the difference between a
 | 
			
		||||
"work based on the library" and a "work that uses the library".  The
 | 
			
		||||
former contains code derived from the library, while the latter only
 | 
			
		||||
works together with the library.
 | 
			
		||||
 | 
			
		||||
  Note that it is possible for a library to be covered by the ordinary
 | 
			
		||||
General Public License rather than by this special one.
 | 
			
		||||
 | 
			
		||||
                  GNU LIBRARY GENERAL PUBLIC LICENSE
 | 
			
		||||
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 | 
			
		||||
 | 
			
		||||
  0. This License Agreement applies to any software library which
 | 
			
		||||
contains a notice placed by the copyright holder or other authorized
 | 
			
		||||
party saying it may be distributed under the terms of this Library
 | 
			
		||||
General Public License (also called "this License").  Each licensee is
 | 
			
		||||
addressed as "you".
 | 
			
		||||
 | 
			
		||||
  A "library" means a collection of software functions and/or data
 | 
			
		||||
prepared so as to be conveniently linked with application programs
 | 
			
		||||
(which use some of those functions and data) to form executables.
 | 
			
		||||
 | 
			
		||||
  The "Library", below, refers to any such software library or work
 | 
			
		||||
which has been distributed under these terms.  A "work based on the
 | 
			
		||||
Library" means either the Library or any derivative work under
 | 
			
		||||
copyright law: that is to say, a work containing the Library or a
 | 
			
		||||
portion of it, either verbatim or with modifications and/or translated
 | 
			
		||||
straightforwardly into another language.  (Hereinafter, translation is
 | 
			
		||||
included without limitation in the term "modification".)
 | 
			
		||||
 | 
			
		||||
  "Source code" for a work means the preferred form of the work for
 | 
			
		||||
making modifications to it.  For a library, complete source code means
 | 
			
		||||
all the source code for all modules it contains, plus any associated
 | 
			
		||||
interface definition files, plus the scripts used to control compilation
 | 
			
		||||
and installation of the library.
 | 
			
		||||
 | 
			
		||||
  Activities other than copying, distribution and modification are not
 | 
			
		||||
covered by this License; they are outside its scope.  The act of
 | 
			
		||||
running a program using the Library is not restricted, and output from
 | 
			
		||||
such a program is covered only if its contents constitute a work based
 | 
			
		||||
on the Library (independent of the use of the Library in a tool for
 | 
			
		||||
writing it).  Whether that is true depends on what the Library does
 | 
			
		||||
and what the program that uses the Library does.
 | 
			
		||||
  
 | 
			
		||||
  1. You may copy and distribute verbatim copies of the Library's
 | 
			
		||||
complete source code as you receive it, in any medium, provided that
 | 
			
		||||
you conspicuously and appropriately publish on each copy an
 | 
			
		||||
appropriate copyright notice and disclaimer of warranty; keep intact
 | 
			
		||||
all the notices that refer to this License and to the absence of any
 | 
			
		||||
warranty; and distribute a copy of this License along with the
 | 
			
		||||
Library.
 | 
			
		||||
 | 
			
		||||
  You may charge a fee for the physical act of transferring a copy,
 | 
			
		||||
and you may at your option offer warranty protection in exchange for a
 | 
			
		||||
fee.
 | 
			
		||||
 | 
			
		||||
  2. You may modify your copy or copies of the Library or any portion
 | 
			
		||||
of it, thus forming a work based on the Library, and copy and
 | 
			
		||||
distribute such modifications or work under the terms of Section 1
 | 
			
		||||
above, provided that you also meet all of these conditions:
 | 
			
		||||
 | 
			
		||||
    a) The modified work must itself be a software library.
 | 
			
		||||
 | 
			
		||||
    b) You must cause the files modified to carry prominent notices
 | 
			
		||||
    stating that you changed the files and the date of any change.
 | 
			
		||||
 | 
			
		||||
    c) You must cause the whole of the work to be licensed at no
 | 
			
		||||
    charge to all third parties under the terms of this License.
 | 
			
		||||
 | 
			
		||||
    d) If a facility in the modified Library refers to a function or a
 | 
			
		||||
    table of data to be supplied by an application program that uses
 | 
			
		||||
    the facility, other than as an argument passed when the facility
 | 
			
		||||
    is invoked, then you must make a good faith effort to ensure that,
 | 
			
		||||
    in the event an application does not supply such function or
 | 
			
		||||
    table, the facility still operates, and performs whatever part of
 | 
			
		||||
    its purpose remains meaningful.
 | 
			
		||||
 | 
			
		||||
    (For example, a function in a library to compute square roots has
 | 
			
		||||
    a purpose that is entirely well-defined independent of the
 | 
			
		||||
    application.  Therefore, Subsection 2d requires that any
 | 
			
		||||
    application-supplied function or table used by this function must
 | 
			
		||||
    be optional: if the application does not supply it, the square
 | 
			
		||||
    root function must still compute square roots.)
 | 
			
		||||
 | 
			
		||||
These requirements apply to the modified work as a whole.  If
 | 
			
		||||
identifiable sections of that work are not derived from the Library,
 | 
			
		||||
and can be reasonably considered independent and separate works in
 | 
			
		||||
themselves, then this License, and its terms, do not apply to those
 | 
			
		||||
sections when you distribute them as separate works.  But when you
 | 
			
		||||
distribute the same sections as part of a whole which is a work based
 | 
			
		||||
on the Library, the distribution of the whole must be on the terms of
 | 
			
		||||
this License, whose permissions for other licensees extend to the
 | 
			
		||||
entire whole, and thus to each and every part regardless of who wrote
 | 
			
		||||
it.
 | 
			
		||||
 | 
			
		||||
Thus, it is not the intent of this section to claim rights or contest
 | 
			
		||||
your rights to work written entirely by you; rather, the intent is to
 | 
			
		||||
exercise the right to control the distribution of derivative or
 | 
			
		||||
collective works based on the Library.
 | 
			
		||||
 | 
			
		||||
In addition, mere aggregation of another work not based on the Library
 | 
			
		||||
with the Library (or with a work based on the Library) on a volume of
 | 
			
		||||
a storage or distribution medium does not bring the other work under
 | 
			
		||||
the scope of this License.
 | 
			
		||||
 | 
			
		||||
  3. You may opt to apply the terms of the ordinary GNU General Public
 | 
			
		||||
License instead of this License to a given copy of the Library.  To do
 | 
			
		||||
this, you must alter all the notices that refer to this License, so
 | 
			
		||||
that they refer to the ordinary GNU General Public License, version 2,
 | 
			
		||||
instead of to this License.  (If a newer version than version 2 of the
 | 
			
		||||
ordinary GNU General Public License has appeared, then you can specify
 | 
			
		||||
that version instead if you wish.)  Do not make any other change in
 | 
			
		||||
these notices.
 | 
			
		||||
 | 
			
		||||
  Once this change is made in a given copy, it is irreversible for
 | 
			
		||||
that copy, so the ordinary GNU General Public License applies to all
 | 
			
		||||
subsequent copies and derivative works made from that copy.
 | 
			
		||||
 | 
			
		||||
  This option is useful when you wish to copy part of the code of
 | 
			
		||||
the Library into a program that is not a library.
 | 
			
		||||
 | 
			
		||||
  4. You may copy and distribute the Library (or a portion or
 | 
			
		||||
derivative of it, under Section 2) in object code or executable form
 | 
			
		||||
under the terms of Sections 1 and 2 above provided that you accompany
 | 
			
		||||
it with the complete corresponding machine-readable source code, which
 | 
			
		||||
must be distributed under the terms of Sections 1 and 2 above on a
 | 
			
		||||
medium customarily used for software interchange.
 | 
			
		||||
 | 
			
		||||
  If distribution of object code is made by offering access to copy
 | 
			
		||||
from a designated place, then offering equivalent access to copy the
 | 
			
		||||
source code from the same place satisfies the requirement to
 | 
			
		||||
distribute the source code, even though third parties are not
 | 
			
		||||
compelled to copy the source along with the object code.
 | 
			
		||||
 | 
			
		||||
  5. A program that contains no derivative of any portion of the
 | 
			
		||||
Library, but is designed to work with the Library by being compiled or
 | 
			
		||||
linked with it, is called a "work that uses the Library".  Such a
 | 
			
		||||
work, in isolation, is not a derivative work of the Library, and
 | 
			
		||||
therefore falls outside the scope of this License.
 | 
			
		||||
 | 
			
		||||
  However, linking a "work that uses the Library" with the Library
 | 
			
		||||
creates an executable that is a derivative of the Library (because it
 | 
			
		||||
contains portions of the Library), rather than a "work that uses the
 | 
			
		||||
library".  The executable is therefore covered by this License.
 | 
			
		||||
Section 6 states terms for distribution of such executables.
 | 
			
		||||
 | 
			
		||||
  When a "work that uses the Library" uses material from a header file
 | 
			
		||||
that is part of the Library, the object code for the work may be a
 | 
			
		||||
derivative work of the Library even though the source code is not.
 | 
			
		||||
Whether this is true is especially significant if the work can be
 | 
			
		||||
linked without the Library, or if the work is itself a library.  The
 | 
			
		||||
threshold for this to be true is not precisely defined by law.
 | 
			
		||||
 | 
			
		||||
  If such an object file uses only numerical parameters, data
 | 
			
		||||
structure layouts and accessors, and small macros and small inline
 | 
			
		||||
functions (ten lines or less in length), then the use of the object
 | 
			
		||||
file is unrestricted, regardless of whether it is legally a derivative
 | 
			
		||||
work.  (Executables containing this object code plus portions of the
 | 
			
		||||
Library will still fall under Section 6.)
 | 
			
		||||
 | 
			
		||||
  Otherwise, if the work is a derivative of the Library, you may
 | 
			
		||||
distribute the object code for the work under the terms of Section 6.
 | 
			
		||||
Any executables containing that work also fall under Section 6,
 | 
			
		||||
whether or not they are linked directly with the Library itself.
 | 
			
		||||
 | 
			
		||||
  6. As an exception to the Sections above, you may also compile or
 | 
			
		||||
link a "work that uses the Library" with the Library to produce a
 | 
			
		||||
work containing portions of the Library, and distribute that work
 | 
			
		||||
under terms of your choice, provided that the terms permit
 | 
			
		||||
modification of the work for the customer's own use and reverse
 | 
			
		||||
engineering for debugging such modifications.
 | 
			
		||||
 | 
			
		||||
  You must give prominent notice with each copy of the work that the
 | 
			
		||||
Library is used in it and that the Library and its use are covered by
 | 
			
		||||
this License.  You must supply a copy of this License.  If the work
 | 
			
		||||
during execution displays copyright notices, you must include the
 | 
			
		||||
copyright notice for the Library among them, as well as a reference
 | 
			
		||||
directing the user to the copy of this License.  Also, you must do one
 | 
			
		||||
of these things:
 | 
			
		||||
 | 
			
		||||
    a) Accompany the work with the complete corresponding
 | 
			
		||||
    machine-readable source code for the Library including whatever
 | 
			
		||||
    changes were used in the work (which must be distributed under
 | 
			
		||||
    Sections 1 and 2 above); and, if the work is an executable linked
 | 
			
		||||
    with the Library, with the complete machine-readable "work that
 | 
			
		||||
    uses the Library", as object code and/or source code, so that the
 | 
			
		||||
    user can modify the Library and then relink to produce a modified
 | 
			
		||||
    executable containing the modified Library.  (It is understood
 | 
			
		||||
    that the user who changes the contents of definitions files in the
 | 
			
		||||
    Library will not necessarily be able to recompile the application
 | 
			
		||||
    to use the modified definitions.)
 | 
			
		||||
 | 
			
		||||
    b) Accompany the work with a written offer, valid for at
 | 
			
		||||
    least three years, to give the same user the materials
 | 
			
		||||
    specified in Subsection 6a, above, for a charge no more
 | 
			
		||||
    than the cost of performing this distribution.
 | 
			
		||||
 | 
			
		||||
    c) If distribution of the work is made by offering access to copy
 | 
			
		||||
    from a designated place, offer equivalent access to copy the above
 | 
			
		||||
    specified materials from the same place.
 | 
			
		||||
 | 
			
		||||
    d) Verify that the user has already received a copy of these
 | 
			
		||||
    materials or that you have already sent this user a copy.
 | 
			
		||||
 | 
			
		||||
  For an executable, the required form of the "work that uses the
 | 
			
		||||
Library" must include any data and utility programs needed for
 | 
			
		||||
reproducing the executable from it.  However, as a special exception,
 | 
			
		||||
the source code distributed need not include anything that is normally
 | 
			
		||||
distributed (in either source or binary form) with the major
 | 
			
		||||
components (compiler, kernel, and so on) of the operating system on
 | 
			
		||||
which the executable runs, unless that component itself accompanies
 | 
			
		||||
the executable.
 | 
			
		||||
 | 
			
		||||
  It may happen that this requirement contradicts the license
 | 
			
		||||
restrictions of other proprietary libraries that do not normally
 | 
			
		||||
accompany the operating system.  Such a contradiction means you cannot
 | 
			
		||||
use both them and the Library together in an executable that you
 | 
			
		||||
distribute.
 | 
			
		||||
 | 
			
		||||
  7. You may place library facilities that are a work based on the
 | 
			
		||||
Library side-by-side in a single library together with other library
 | 
			
		||||
facilities not covered by this License, and distribute such a combined
 | 
			
		||||
library, provided that the separate distribution of the work based on
 | 
			
		||||
the Library and of the other library facilities is otherwise
 | 
			
		||||
permitted, and provided that you do these two things:
 | 
			
		||||
 | 
			
		||||
    a) Accompany the combined library with a copy of the same work
 | 
			
		||||
    based on the Library, uncombined with any other library
 | 
			
		||||
    facilities.  This must be distributed under the terms of the
 | 
			
		||||
    Sections above.
 | 
			
		||||
 | 
			
		||||
    b) Give prominent notice with the combined library of the fact
 | 
			
		||||
    that part of it is a work based on the Library, and explaining
 | 
			
		||||
    where to find the accompanying uncombined form of the same work.
 | 
			
		||||
 | 
			
		||||
  8. You may not copy, modify, sublicense, link with, or distribute
 | 
			
		||||
the Library except as expressly provided under this License.  Any
 | 
			
		||||
attempt otherwise to copy, modify, sublicense, link with, or
 | 
			
		||||
distribute the Library is void, and will automatically terminate your
 | 
			
		||||
rights under this License.  However, parties who have received copies,
 | 
			
		||||
or rights, from you under this License will not have their licenses
 | 
			
		||||
terminated so long as such parties remain in full compliance.
 | 
			
		||||
 | 
			
		||||
  9. You are not required to accept this License, since you have not
 | 
			
		||||
signed it.  However, nothing else grants you permission to modify or
 | 
			
		||||
distribute the Library or its derivative works.  These actions are
 | 
			
		||||
prohibited by law if you do not accept this License.  Therefore, by
 | 
			
		||||
modifying or distributing the Library (or any work based on the
 | 
			
		||||
Library), you indicate your acceptance of this License to do so, and
 | 
			
		||||
all its terms and conditions for copying, distributing or modifying
 | 
			
		||||
the Library or works based on it.
 | 
			
		||||
 | 
			
		||||
  10. Each time you redistribute the Library (or any work based on the
 | 
			
		||||
Library), the recipient automatically receives a license from the
 | 
			
		||||
original licensor to copy, distribute, link with or modify the Library
 | 
			
		||||
subject to these terms and conditions.  You may not impose any further
 | 
			
		||||
restrictions on the recipients' exercise of the rights granted herein.
 | 
			
		||||
You are not responsible for enforcing compliance by third parties to
 | 
			
		||||
this License.
 | 
			
		||||
 | 
			
		||||
  11. If, as a consequence of a court judgment or allegation of patent
 | 
			
		||||
infringement or for any other reason (not limited to patent issues),
 | 
			
		||||
conditions are imposed on you (whether by court order, agreement or
 | 
			
		||||
otherwise) that contradict the conditions of this License, they do not
 | 
			
		||||
excuse you from the conditions of this License.  If you cannot
 | 
			
		||||
distribute so as to satisfy simultaneously your obligations under this
 | 
			
		||||
License and any other pertinent obligations, then as a consequence you
 | 
			
		||||
may not distribute the Library at all.  For example, if a patent
 | 
			
		||||
license would not permit royalty-free redistribution of the Library by
 | 
			
		||||
all those who receive copies directly or indirectly through you, then
 | 
			
		||||
the only way you could satisfy both it and this License would be to
 | 
			
		||||
refrain entirely from distribution of the Library.
 | 
			
		||||
 | 
			
		||||
If any portion of this section is held invalid or unenforceable under any
 | 
			
		||||
particular circumstance, the balance of the section is intended to apply,
 | 
			
		||||
and the section as a whole is intended to apply in other circumstances.
 | 
			
		||||
 | 
			
		||||
It is not the purpose of this section to induce you to infringe any
 | 
			
		||||
patents or other property right claims or to contest validity of any
 | 
			
		||||
such claims; this section has the sole purpose of protecting the
 | 
			
		||||
integrity of the free software distribution system which is
 | 
			
		||||
implemented by public license practices.  Many people have made
 | 
			
		||||
generous contributions to the wide range of software distributed
 | 
			
		||||
through that system in reliance on consistent application of that
 | 
			
		||||
system; it is up to the author/donor to decide if he or she is willing
 | 
			
		||||
to distribute software through any other system and a licensee cannot
 | 
			
		||||
impose that choice.
 | 
			
		||||
 | 
			
		||||
This section is intended to make thoroughly clear what is believed to
 | 
			
		||||
be a consequence of the rest of this License.
 | 
			
		||||
 | 
			
		||||
  12. If the distribution and/or use of the Library is restricted in
 | 
			
		||||
certain countries either by patents or by copyrighted interfaces, the
 | 
			
		||||
original copyright holder who places the Library under this License may add
 | 
			
		||||
an explicit geographical distribution limitation excluding those countries,
 | 
			
		||||
so that distribution is permitted only in or among countries not thus
 | 
			
		||||
excluded.  In such case, this License incorporates the limitation as if
 | 
			
		||||
written in the body of this License.
 | 
			
		||||
 | 
			
		||||
  13. The Free Software Foundation may publish revised and/or new
 | 
			
		||||
versions of the Library General Public License from time to time.
 | 
			
		||||
Such new versions will be similar in spirit to the present version,
 | 
			
		||||
but may differ in detail to address new problems or concerns.
 | 
			
		||||
 | 
			
		||||
Each version is given a distinguishing version number.  If the Library
 | 
			
		||||
specifies a version number of this License which applies to it and
 | 
			
		||||
"any later version", you have the option of following the terms and
 | 
			
		||||
conditions either of that version or of any later version published by
 | 
			
		||||
the Free Software Foundation.  If the Library does not specify a
 | 
			
		||||
license version number, you may choose any version ever published by
 | 
			
		||||
the Free Software Foundation.
 | 
			
		||||
 | 
			
		||||
  14. If you wish to incorporate parts of the Library into other free
 | 
			
		||||
programs whose distribution conditions are incompatible with these,
 | 
			
		||||
write to the author to ask for permission.  For software which is
 | 
			
		||||
copyrighted by the Free Software Foundation, write to the Free
 | 
			
		||||
Software Foundation; we sometimes make exceptions for this.  Our
 | 
			
		||||
decision will be guided by the two goals of preserving the free status
 | 
			
		||||
of all derivatives of our free software and of promoting the sharing
 | 
			
		||||
and reuse of software generally.
 | 
			
		||||
 | 
			
		||||
                            NO WARRANTY
 | 
			
		||||
 | 
			
		||||
  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
 | 
			
		||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
 | 
			
		||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
 | 
			
		||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
 | 
			
		||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 | 
			
		||||
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
 | 
			
		||||
LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
 | 
			
		||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
 | 
			
		||||
 | 
			
		||||
  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
 | 
			
		||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
 | 
			
		||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
 | 
			
		||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
 | 
			
		||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
 | 
			
		||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
 | 
			
		||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
 | 
			
		||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
 | 
			
		||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 | 
			
		||||
DAMAGES.
 | 
			
		||||
 | 
			
		||||
                     END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
           How to Apply These Terms to Your New Libraries
 | 
			
		||||
 | 
			
		||||
  If you develop a new library, and you want it to be of the greatest
 | 
			
		||||
possible use to the public, we recommend making it free software that
 | 
			
		||||
everyone can redistribute and change.  You can do so by permitting
 | 
			
		||||
redistribution under these terms (or, alternatively, under the terms of the
 | 
			
		||||
ordinary General Public License).
 | 
			
		||||
 | 
			
		||||
  To apply these terms, attach the following notices to the library.  It is
 | 
			
		||||
safest to attach them to the start of each source file to most effectively
 | 
			
		||||
convey the exclusion of warranty; and each file should have at least the
 | 
			
		||||
"copyright" line and a pointer to where the full notice is found.
 | 
			
		||||
 | 
			
		||||
    <one line to give the library's name and a brief idea of what it does.>
 | 
			
		||||
    Copyright (C) <year>  <name of author>
 | 
			
		||||
 | 
			
		||||
    This library is free software; you can redistribute it and/or
 | 
			
		||||
    modify it under the terms of the GNU Library General Public
 | 
			
		||||
    License as published by the Free Software Foundation; either
 | 
			
		||||
    version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
    This library is distributed in the hope that it will be useful,
 | 
			
		||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
    Library General Public License for more details.
 | 
			
		||||
 | 
			
		||||
    You should have received a copy of the GNU Library General Public
 | 
			
		||||
    License along with this library; if not, write to the Free Software
 | 
			
		||||
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
 | 
			
		||||
Also add information on how to contact you by electronic and paper mail.
 | 
			
		||||
 | 
			
		||||
You should also get your employer (if you work as a programmer) or your
 | 
			
		||||
school, if any, to sign a "copyright disclaimer" for the library, if
 | 
			
		||||
necessary.  Here is a sample; alter the names:
 | 
			
		||||
 | 
			
		||||
  Yoyodyne, Inc., hereby disclaims all copyright interest in the
 | 
			
		||||
  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
 | 
			
		||||
 | 
			
		||||
  <signature of Ty Coon>, 1 April 1990
 | 
			
		||||
  Ty Coon, President of Vice
 | 
			
		||||
 | 
			
		||||
That's all there is to it!
 | 
			
		||||
							
								
								
									
										34
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								README.md
									
									
									
									
									
								
							@@ -5,30 +5,30 @@
 | 
			
		||||
# Calamares: Distribution-Independent Installer Framework
 | 
			
		||||
---------
 | 
			
		||||
 | 
			
		||||
[](https://github.com/calamares/calamares/labels/hacking%3A%20in-progress)
 | 
			
		||||
[](https://github.com/calamares/calamares/releases)
 | 
			
		||||
[](https://travis-ci.org/calamares/calamares)
 | 
			
		||||
[](https://scan.coverity.com/projects/5389)
 | 
			
		||||
[](https://github.com/calamares/calamares/blob/calamares/LICENSE)
 | 
			
		||||
[](https://github.com/calamares/calamares/actions?query=workflow%3Aci)
 | 
			
		||||
[](https://github.com/calamares/calamares/tree/calamares/LICENSES)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| [Report a Bug](https://github.com/calamares/calamares/issues/new) | [Translate](https://www.transifex.com/projects/p/calamares/) | [Contribute](CONTRIBUTING.md) | [Freenode (IRC): #calamares](https://webchat.freenode.net/?channel=#calamares?nick=guest) | [Wiki](https://github.com/calamares/calamares/wiki) |
 | 
			
		||||
| [Report a Bug](https://github.com/calamares/calamares/issues/new) | [Translate](https://app.transifex.com/calamares/calamares/) | [Contribute](CONTRIBUTING.md) | [Chat on Matrix: #calamares:kde.org](https://webchat.kde.org/#/room/%23calamares:kde.org) | [Wiki](https://github.com/calamares/calamares/wiki) |
 | 
			
		||||
|:--:|:--:|:--:|:--:|:--:|
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
> Calamares is a distribution-independent system installer, with an advanced partitioning
 | 
			
		||||
> feature for both manual and automated partitioning operations. Calamares is designed to
 | 
			
		||||
> be customizable by distribution maintainers without need for cumbersome patching,
 | 
			
		||||
> thanks to third party branding and external modules support.
 | 
			
		||||
> be customizable by distribution maintainers without the need for cumbersome patching,
 | 
			
		||||
> thanks to third-party branding and external modules support.
 | 
			
		||||
 | 
			
		||||
## Target Audience
 | 
			
		||||
 | 
			
		||||
Calamares is a Linux installer; users who install Linux on a computer will hopefully
 | 
			
		||||
use it just **once**, to install their Linux distribution. Calamares is not
 | 
			
		||||
a "ready to use" application: distributions apply a huge amount of customisation
 | 
			
		||||
a "ready to use" application: distributions apply a huge amount of customization
 | 
			
		||||
and configuration to Calamares, and the target audience for this repository
 | 
			
		||||
is those distributions, and the people who make those Linux distro's.
 | 
			
		||||
is those distributions, and the people who make those Linux distros.
 | 
			
		||||
 | 
			
		||||
Calamares has some [generic user documentation](https://github.com/calamares/calamares/wiki/Use-Guide)
 | 
			
		||||
Calamares has some [generic user documentation](https://calamares.io/docs/users-guide/)
 | 
			
		||||
for end-users, but most of what we have is for distro developers.
 | 
			
		||||
 | 
			
		||||
## Getting Calamares
 | 
			
		||||
@@ -45,19 +45,23 @@ The dependencies are explained in [CONTRIBUTING.md](CONTRIBUTING.md).
 | 
			
		||||
## Contributing to Calamares
 | 
			
		||||
 | 
			
		||||
Calamares welcomes PRs. New issues are welcome, too.
 | 
			
		||||
There are both the Calamares **core** repository (this one),
 | 
			
		||||
and an *extensions** repository ([Calamares extensions](https://github.com/calamares/calamares-extensions).
 | 
			
		||||
There are both the Calamares **core** repository (this one)
 | 
			
		||||
and an **extensions** repository ([Calamares extensions](https://github.com/calamares/calamares-extensions)).
 | 
			
		||||
 | 
			
		||||
Contributions to code, modules, documentation, the wiki and the website are all welcome.
 | 
			
		||||
Contributions to code, modules, documentation, the wiki, and the website are all welcome.
 | 
			
		||||
There is more information in the [CONTRIBUTING.md](CONTRIBUTING.md) file.
 | 
			
		||||
 | 
			
		||||
## Join the Conversation
 | 
			
		||||
 | 
			
		||||
GitHub Issues are **one** place for discussing Calamares if there are concrete
 | 
			
		||||
problems or a new feature to discuss.
 | 
			
		||||
Issues are not a help channel.
 | 
			
		||||
Visit Matrix for help with configuration or compilation.
 | 
			
		||||
 | 
			
		||||
Regular Calamares development chit-chat happens on old-school IRC
 | 
			
		||||
(no registration required). Responsiveness is best during the day
 | 
			
		||||
Regular Calamares development chit-chat happens in a [Matrix](https://matrix.org/)
 | 
			
		||||
room, `#calamares:kde.org`. Responsiveness is best during the day
 | 
			
		||||
in Europe, but feel free to idle.
 | 
			
		||||
Matrix is persistent, and we'll see your message eventually.
 | 
			
		||||
 | 
			
		||||
* [](https://webchat.kde.org/#/room/%23calamares:kde.org) (needs a Matrix account)
 | 
			
		||||
 | 
			
		||||
[](https://webchat.freenode.net/?channel=#calamares?nick=guest|)
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@ Name=Install System
 | 
			
		||||
GenericName=System Installer
 | 
			
		||||
Keywords=calamares;system;installer;
 | 
			
		||||
TryExec=calamares
 | 
			
		||||
Exec=pkexec /usr/bin/calamares
 | 
			
		||||
Exec=sh -c "pkexec calamares"
 | 
			
		||||
Comment=Calamares — System Installer
 | 
			
		||||
Icon=calamares
 | 
			
		||||
Terminal=false
 | 
			
		||||
@@ -21,18 +21,26 @@ Name[as]=চিছটেম ইনস্তল কৰক
 | 
			
		||||
Icon[as]=কেলামাৰেচ
 | 
			
		||||
GenericName[as]=চিছটেম ইনস্তলাৰ
 | 
			
		||||
Comment[as]=কেলামাৰেচ — চিছটেম ইনস্তলাৰ
 | 
			
		||||
Name[ast]=Instalar el sistema
 | 
			
		||||
Icon[ast]=calamares
 | 
			
		||||
GenericName[ast]=Instalador del sistema
 | 
			
		||||
Comment[ast]=Calamares — Instalador del sistema
 | 
			
		||||
Name[az]=Sistemi Quraşdırmaq
 | 
			
		||||
Icon[az]=calamares
 | 
			
		||||
GenericName[az]=Sistem Quraşdırıcısı
 | 
			
		||||
Comment[az]=Calamares Sistem Quraşdırıcısı
 | 
			
		||||
Name[az_AZ]=Sistemi quraşdırmaq
 | 
			
		||||
Icon[az_AZ]=calamares
 | 
			
		||||
GenericName[az_AZ]=Sistem quraşdırcısı
 | 
			
		||||
Comment[az_AZ]=Calamares — Sistem Quraşdırıcısı
 | 
			
		||||
Name[be]=Усталяваць сістэму
 | 
			
		||||
Icon[be]=calamares
 | 
			
		||||
GenericName[be]=Усталёўшчык сістэмы
 | 
			
		||||
Comment[be]=Calamares — усталёўшчык сістэмы
 | 
			
		||||
Name[bg]=Инсталирай системата
 | 
			
		||||
Icon[bg]=calamares
 | 
			
		||||
GenericName[bg]=Системен Инсталатор
 | 
			
		||||
Comment[bg]=Calamares — Системен Инсталатор
 | 
			
		||||
GenericName[bg]=Системен инсталатор
 | 
			
		||||
Comment[bg]=„Calamares“ – Системен инсталатор
 | 
			
		||||
Name[bn]=সিস্টেম ইনস্টল করুন
 | 
			
		||||
Icon[bn]=ক্যালামারেস
 | 
			
		||||
GenericName[bn]=সিস্টেম ইনস্টলার
 | 
			
		||||
@@ -41,6 +49,10 @@ Name[ca]=Instal·la el sistema
 | 
			
		||||
Icon[ca]=calamares
 | 
			
		||||
GenericName[ca]=Instal·lador de sistema
 | 
			
		||||
Comment[ca]=Calamares — Instal·lador de sistema
 | 
			
		||||
Name[cs_CZ]=Nainstalovat systém
 | 
			
		||||
Icon[cs_CZ]=calamares
 | 
			
		||||
GenericName[cs_CZ]=Instalátor systému
 | 
			
		||||
Comment[cs_CZ]=Calamares – instalátor operačních systémů
 | 
			
		||||
Name[da]=Installér system
 | 
			
		||||
Icon[da]=calamares
 | 
			
		||||
GenericName[da]=Systeminstallationsprogram
 | 
			
		||||
@@ -57,10 +69,19 @@ Name[en_GB]=Install System
 | 
			
		||||
Icon[en_GB]=calamares
 | 
			
		||||
GenericName[en_GB]=System Installer
 | 
			
		||||
Comment[en_GB]=Calamares — System Installer
 | 
			
		||||
Name[es]=Instalar Sistema
 | 
			
		||||
Name[eo]=Instali Sistemo
 | 
			
		||||
Icon[eo]=calamares
 | 
			
		||||
GenericName[eo]=Sistema Instalilo
 | 
			
		||||
Comment[eo]=Calamares — Sistema Instalilo
 | 
			
		||||
Name[es]=Instalar el sistema
 | 
			
		||||
Icon[es]=calamares
 | 
			
		||||
GenericName[es]=Instalador del Sistema
 | 
			
		||||
Comment[es]=Calamares — Instalador del Sistema
 | 
			
		||||
GenericName[es]=Instalador del sistema
 | 
			
		||||
Comment[es]=Calamares — Instalador del sistema
 | 
			
		||||
Name[es_MX]=Instalar el Sistema
 | 
			
		||||
Icon[es_MX]=calamares
 | 
			
		||||
GenericName[es_MX]=Instalador del sistema
 | 
			
		||||
Comment[es_MX]=Calamares - Instalador del sistema
 | 
			
		||||
Name[es_PR]=Instalar el sistema
 | 
			
		||||
Name[et]=Paigalda süsteem
 | 
			
		||||
Icon[et]=calamares
 | 
			
		||||
GenericName[et]=Süsteemipaigaldaja
 | 
			
		||||
@@ -71,9 +92,12 @@ GenericName[eu]=Sistema instalatzailea
 | 
			
		||||
Comment[eu]=Calamares - sistema instalatzailea
 | 
			
		||||
Name[fa]=نصب سامانه
 | 
			
		||||
Icon[fa]=کالامارس
 | 
			
		||||
GenericName[fa]=نصبکنندهٔ سامانه
 | 
			
		||||
Comment[fa]=کالامارس — نصبکنندهٔ سامانه
 | 
			
		||||
Name[es_PR]=Instalar el sistema
 | 
			
		||||
GenericName[fa]=نصبکننده سامانه
 | 
			
		||||
Comment[fa]=کالامارس — نصبکننده سامانه
 | 
			
		||||
Name[fi_FI]=Asenna järjestelmä
 | 
			
		||||
Icon[fi_FI]=calamares
 | 
			
		||||
GenericName[fi_FI]=Järjestelmän asennusohjelma
 | 
			
		||||
Comment[fi_FI]=Calamares — Järjestelmän asentaja
 | 
			
		||||
Name[fr]=Installer le système
 | 
			
		||||
Icon[fr]=calamares
 | 
			
		||||
GenericName[fr]=Installateur système
 | 
			
		||||
@@ -98,10 +122,6 @@ Name[hr]=Instaliraj sustav
 | 
			
		||||
Icon[hr]=calamares
 | 
			
		||||
GenericName[hr]=Instalacija sustava
 | 
			
		||||
Comment[hr]=Calamares — Instalacija sustava
 | 
			
		||||
Name[ie]=Installar li sistema
 | 
			
		||||
Icon[ie]=calamares
 | 
			
		||||
GenericName[ie]=Installator del sistema
 | 
			
		||||
Comment[ie]=Calamares — Installator del sistema
 | 
			
		||||
Name[hu]=Rendszer telepítése
 | 
			
		||||
Icon[hu]=calamares
 | 
			
		||||
GenericName[hu]=Rendszertelepítő
 | 
			
		||||
@@ -110,14 +130,18 @@ Name[id]=Instal Sistem
 | 
			
		||||
Icon[id]=calamares
 | 
			
		||||
GenericName[id]=Pemasang
 | 
			
		||||
Comment[id]=Calamares — Pemasang Sistem
 | 
			
		||||
Name[ie]=Installar li sistema
 | 
			
		||||
Icon[ie]=calamares
 | 
			
		||||
GenericName[ie]=Installator del sistema
 | 
			
		||||
Comment[ie]=Calamares — Installator del sistema
 | 
			
		||||
Name[is]=Setja upp kerfið
 | 
			
		||||
Icon[is]=calamares
 | 
			
		||||
GenericName[is]=Kerfis uppsetning
 | 
			
		||||
Comment[is]=Calamares — Kerfis uppsetning
 | 
			
		||||
Name[cs_CZ]=Nainstalovat systém
 | 
			
		||||
Icon[cs_CZ]=calamares
 | 
			
		||||
GenericName[cs_CZ]=Instalátor systému
 | 
			
		||||
Comment[cs_CZ]=Calamares – instalátor operačních systémů
 | 
			
		||||
Name[it_IT]=Installa il sistema
 | 
			
		||||
Icon[it_IT]=calamares
 | 
			
		||||
GenericName[it_IT]=Programma d'installazione del sistema
 | 
			
		||||
Comment[it_IT]=Calamares — Programma d'installazione del sistema
 | 
			
		||||
Name[ja]=システムをインストール
 | 
			
		||||
Icon[ja]=calamares
 | 
			
		||||
GenericName[ja]=システムインストーラー
 | 
			
		||||
@@ -130,10 +154,6 @@ Name[lt]=Įdiegti Sistemą
 | 
			
		||||
Icon[lt]=calamares
 | 
			
		||||
GenericName[lt]=Sistemos diegimas į kompiuterį
 | 
			
		||||
Comment[lt]=Calamares — Sistemos diegimo programa
 | 
			
		||||
Name[it_IT]=Installa il sistema
 | 
			
		||||
Icon[it_IT]=calamares
 | 
			
		||||
GenericName[it_IT]=Programma d'installazione del sistema
 | 
			
		||||
Comment[it_IT]=Calamares — Programma d'installazione del sistema
 | 
			
		||||
Name[mk]=Инсталирај го системот
 | 
			
		||||
Icon[mk]=calamares
 | 
			
		||||
GenericName[mk]=Системен Инсталер
 | 
			
		||||
@@ -146,14 +166,14 @@ Name[nb]=Installer System
 | 
			
		||||
Icon[nb]=calamares
 | 
			
		||||
GenericName[nb]=Systeminstallatør
 | 
			
		||||
Comment[nb]=Calamares-systeminstallatør
 | 
			
		||||
Name[ne_NP]= सिस्टम इन्स्टल गर्नुहोस्
 | 
			
		||||
Icon[ne_NP]=Calamares
 | 
			
		||||
GenericName[ne_NP]=सिस्टम इन्स्टलर
 | 
			
		||||
Comment[ne_NP]=Calamares - सिस्टम इन्स्टलर
 | 
			
		||||
Name[nl]=Installeer systeem
 | 
			
		||||
Icon[nl]=calamares
 | 
			
		||||
GenericName[nl]=Installatieprogramma
 | 
			
		||||
Comment[nl]=Calamares — Installatieprogramma
 | 
			
		||||
Name[az_AZ]=Sistemi quraşdırmaq
 | 
			
		||||
Icon[az_AZ]=calamares
 | 
			
		||||
GenericName[az_AZ]=Sistem quraşdırcısı
 | 
			
		||||
Comment[az_AZ]=Calamares — Sistem Quraşdırıcısı
 | 
			
		||||
Name[pl]=Zainstaluj system
 | 
			
		||||
Icon[pl]=calamares
 | 
			
		||||
GenericName[pl]=Instalator systemu
 | 
			
		||||
@@ -162,6 +182,10 @@ Name[pt_BR]=Sistema de Instalação
 | 
			
		||||
Icon[pt_BR]=calamares
 | 
			
		||||
GenericName[pt_BR]=Instalador de Sistema
 | 
			
		||||
Comment[pt_BR]=Calamares — Instalador de Sistema
 | 
			
		||||
Name[pt_PT]=Instalar Sistema
 | 
			
		||||
Icon[pt_PT]=calamares
 | 
			
		||||
GenericName[pt_PT]=Instalador de Sistema
 | 
			
		||||
Comment[pt_PT]=Instalador de Sistema - Calamares
 | 
			
		||||
Name[ro]=Instalează sistemul
 | 
			
		||||
Icon[ro]=calamares
 | 
			
		||||
GenericName[ro]=Instalator de sistem
 | 
			
		||||
@@ -170,6 +194,10 @@ Name[ru]=Установить систему
 | 
			
		||||
Icon[ru]=calamares
 | 
			
		||||
GenericName[ru]=Установщик системы
 | 
			
		||||
Comment[ru]=Calamares - Установщик системы
 | 
			
		||||
Name[si]=පද්ධතිය ස්ථාපනය කරන්න
 | 
			
		||||
Icon[si]=කැලමරේස්
 | 
			
		||||
GenericName[si]=පද්ධති ස්ථාපකය
 | 
			
		||||
Comment[si]=Calamares - පද්ධති ස්ථාපකය
 | 
			
		||||
Name[sk]=Inštalovať systém
 | 
			
		||||
Icon[sk]=calamares
 | 
			
		||||
GenericName[sk]=Inštalátor systému
 | 
			
		||||
@@ -179,15 +207,11 @@ Name[sq]=Instalo Sistemin
 | 
			
		||||
Icon[sq]=calamares
 | 
			
		||||
GenericName[sq]=Instalues Sistemi
 | 
			
		||||
Comment[sq]=Calamares — Instalues Sistemi
 | 
			
		||||
Name[fi_FI]=Asenna Järjestelmä
 | 
			
		||||
Icon[fi_FI]=calamares
 | 
			
		||||
GenericName[fi_FI]=Järjestelmän Asennusohjelma
 | 
			
		||||
Comment[fi_FI]=Calamares — Järjestelmän Asentaja
 | 
			
		||||
Name[sr@latin]=Instaliraj sistem
 | 
			
		||||
Name[sr]=Инсталирај систем
 | 
			
		||||
Icon[sr]=calamares
 | 
			
		||||
GenericName[sr]=Инсталатер система
 | 
			
		||||
Comment[sr]=Каламарес — инсталатер система
 | 
			
		||||
Name[sr@latin]=Instaliraj sistem
 | 
			
		||||
Name[sv]=Installera system
 | 
			
		||||
Icon[sv]=calamares
 | 
			
		||||
GenericName[sv]=Systeminstallerare
 | 
			
		||||
@@ -197,6 +221,10 @@ Icon[tg]=calamares
 | 
			
		||||
GenericName[tg]=Насбкунандаи низомӣ
 | 
			
		||||
Comment[tg]=Calamares — Насбкунандаи низомӣ
 | 
			
		||||
Name[th]=ติดตั้งระบบ
 | 
			
		||||
Name[tr_TR]=Sistemi Yükle
 | 
			
		||||
Icon[tr_TR]=calamares
 | 
			
		||||
GenericName[tr_TR]=Sistem Yükleyici
 | 
			
		||||
Comment[tr_TR]=Calamares — Sistem Yükleyici
 | 
			
		||||
Name[uk]=Встановити Систему
 | 
			
		||||
Icon[uk]=calamares
 | 
			
		||||
GenericName[uk]=Встановлювач системи
 | 
			
		||||
@@ -213,27 +241,3 @@ Name[zh_TW]=安裝系統
 | 
			
		||||
Icon[zh_TW]=calamares
 | 
			
		||||
GenericName[zh_TW]=系統安裝程式
 | 
			
		||||
Comment[zh_TW]=Calamares ── 系統安裝程式
 | 
			
		||||
Name[ast]=Instalar el sistema
 | 
			
		||||
Icon[ast]=calamares
 | 
			
		||||
GenericName[ast]=Instalador del sistema
 | 
			
		||||
Comment[ast]=Calamares — Instalador del sistema
 | 
			
		||||
Name[eo]=Instali Sistemo
 | 
			
		||||
Icon[eo]=calamares
 | 
			
		||||
GenericName[eo]=Sistema Instalilo
 | 
			
		||||
Comment[eo]=Calamares — Sistema Instalilo
 | 
			
		||||
Name[ne_NP]= सिस्टम इन्स्टल गर्नुहोस्
 | 
			
		||||
Icon[ne_NP]=Calamares
 | 
			
		||||
GenericName[ne_NP]=सिस्टम इन्स्टलर
 | 
			
		||||
Comment[ne_NP]=Calamares - सिस्टम इन्स्टलर
 | 
			
		||||
Name[es_MX]=Instalar el Sistema
 | 
			
		||||
Icon[es_MX]=calamares
 | 
			
		||||
GenericName[es_MX]=Instalador del sistema
 | 
			
		||||
Comment[es_MX]=Calamares - Instalador del sistema
 | 
			
		||||
Name[pt_PT]=Instalar Sistema
 | 
			
		||||
Icon[pt_PT]=calamares
 | 
			
		||||
GenericName[pt_PT]=Instalador de Sistema
 | 
			
		||||
Comment[pt_PT]=Calamares - Instalador de Sistema
 | 
			
		||||
Name[tr_TR]=Sistemi Yükle
 | 
			
		||||
Icon[tr_TR]=calamares
 | 
			
		||||
GenericName[tr_TR]=Sistem Yükleyici
 | 
			
		||||
Comment[tr_TR]=Calamares — Sistem Yükleyici
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@ Name=Install System
 | 
			
		||||
GenericName=System Installer
 | 
			
		||||
Keywords=calamares;system;installer;
 | 
			
		||||
TryExec=calamares
 | 
			
		||||
Exec=pkexec /usr/bin/calamares
 | 
			
		||||
Exec=sh -c "pkexec calamares"
 | 
			
		||||
Comment=Calamares — System Installer
 | 
			
		||||
Icon=calamares
 | 
			
		||||
Terminal=false
 | 
			
		||||
 
 | 
			
		||||
@@ -11,8 +11,31 @@
 | 
			
		||||
>
 | 
			
		||||
> Most things are automated through the release script [RELEASE.sh](RELEASE.sh)
 | 
			
		||||
 | 
			
		||||
## (0) During a release cycle
 | 
			
		||||
 | 
			
		||||
* Fetch latest translations from Transifex. We only push / pull translations
 | 
			
		||||
  from *calamares* branch, so longer-lived branches (e.g. 3.1.x) don't get
 | 
			
		||||
  translation updates. This is to keep the translation workflow simple.
 | 
			
		||||
  The script automatically commits changes to the translations. It's ok
 | 
			
		||||
  to do this during a release cycle. Run `sh ci/txpull.sh`
 | 
			
		||||
  to fetch translations and commit the changes in one go.
 | 
			
		||||
* Push the strings to Transifex. From a checkout, run `ci/txpush.sh`
 | 
			
		||||
* Update the list of enabled translation languages in `CMakeLists.txt`.
 | 
			
		||||
  Check the [translation site][transifex] for the list of languages with
 | 
			
		||||
  fairly complete translations, or use `ci/txstats.py --edit` for an automated
 | 
			
		||||
  suggestion. If there are changes, commit them.
 | 
			
		||||
 | 
			
		||||
## (1) Preparation
 | 
			
		||||
 | 
			
		||||
* Double-check the *CALAMARES_VERSION* value at the top of `CMakeLists.txt`.
 | 
			
		||||
* Set *CALAMARES_RELEASE_MODE* to `ON` in `CMakeLists.txt`.
 | 
			
		||||
* Edit `CHANGES-*` and set the date of the release. Pick the right
 | 
			
		||||
  file for the release-stream.
 | 
			
		||||
* Commit both. This is usually done with commit-message
 | 
			
		||||
  *Changes: pre-release housekeeping*.
 | 
			
		||||
 | 
			
		||||
## (2) Release Preparation
 | 
			
		||||
 | 
			
		||||
* Make sure all tests pass.
 | 
			
		||||
  ```
 | 
			
		||||
    make
 | 
			
		||||
@@ -22,27 +45,16 @@
 | 
			
		||||
  an additional environment variable to be set for some tests, which will
 | 
			
		||||
  destroy an attached disk. This is not always desirable. There are some
 | 
			
		||||
  sample config-files that are empty and which fail the config-tests.
 | 
			
		||||
* Pull latest translations from Transifex. We only push / pull translations
 | 
			
		||||
  from master, so longer-lived branches (e.g. 3.1.x) don't get translation
 | 
			
		||||
  updates. This is to keep the translation workflow simple. The script
 | 
			
		||||
  automatically commits changes to the translations.
 | 
			
		||||
  ```
 | 
			
		||||
    sh ci/txpull.sh
 | 
			
		||||
  ```
 | 
			
		||||
* Update the list of enabled translation languages in `CMakeLists.txt`.
 | 
			
		||||
  Check the [translation site][transifex] for the list of languages with
 | 
			
		||||
  fairly complete translations, or use `ci/txstats.py` for an automated
 | 
			
		||||
  suggestion. If there are changes, commit them.
 | 
			
		||||
* Push the changes.
 | 
			
		||||
* Check defaults in `settings.conf` and other configuration files.
 | 
			
		||||
* Drop the RC variable to 0 in `CMakeLists.txt`, *CALAMARES_VERSION_RC*.
 | 
			
		||||
* Edit `CHANGES` and set the date of the release.
 | 
			
		||||
* Commit both. This is usually done with commit-message
 | 
			
		||||
  *Changes: pre-release housekeeping*.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## (2) Release Day
 | 
			
		||||
 | 
			
		||||
  Note that the release script (see below) also runs the tests and
 | 
			
		||||
  will bail out if any fail.
 | 
			
		||||
* Make sure the translations are up-to-date. There is logic to check
 | 
			
		||||
  for changes in translations: a movable tag *translations* indicates
 | 
			
		||||
  when translations were last pushed, and the logic tries to enforce a
 | 
			
		||||
  week of latency between push-translations and a release, to allow
 | 
			
		||||
  translators to catch up. Run `ci/txcheck.sh` to confirm this.
 | 
			
		||||
  Run `ci/txcheck.sh --cleanup` to tidy up afterwards, and possibly pass
 | 
			
		||||
  `-T` to the release script to skip the translation-age check if you
 | 
			
		||||
  feel it is warranted.
 | 
			
		||||
* Run the helper script `ci/RELEASE.sh` or follow steps below.
 | 
			
		||||
  The script checks:
 | 
			
		||||
  - for uncommitted local changes,
 | 
			
		||||
@@ -64,30 +76,18 @@ Follow the instructions printed by the release script.
 | 
			
		||||
* Upload tarball and signature.
 | 
			
		||||
* Publish release article on `calamares.io`.
 | 
			
		||||
* Close associated milestone on GitHub if it's entirely done.
 | 
			
		||||
* Update topic on #calamares IRC channel.
 | 
			
		||||
* Update topic on `#calamares:kde.org` Matrix channel.
 | 
			
		||||
 | 
			
		||||
## (4) Post-Release
 | 
			
		||||
 | 
			
		||||
* Bump the version number in `CMakeLists.txt` in the `project()` command.
 | 
			
		||||
* Set *CALAMARES_VERSION_RC* back to 1.
 | 
			
		||||
* Add a placeholder entry for the next release in `CHANGES` with date
 | 
			
		||||
  text *not released yet*.
 | 
			
		||||
* Bump the version number in `CMakeLists.txt` in *CALAMARES_VERSION*.
 | 
			
		||||
* Set *CALAMARES_RELEASE_MODE* back to `OFF`.
 | 
			
		||||
* Add a placeholder entry for the next release in `CHANGES-*` with date
 | 
			
		||||
  text *not released yet*. See the text below, "Placeholder Release".
 | 
			
		||||
  Add the placeholder to the right file for the release-stream.
 | 
			
		||||
* Commit and push that, usually with the message
 | 
			
		||||
  *Changes: post-release housekeeping*.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
# 3.2.XX (unreleased) #
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - No external contributors yet
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - No core changes yet
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - No module changes yet
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
# Related Material
 | 
			
		||||
 | 
			
		||||
> This section isn't directly related to any specific release,
 | 
			
		||||
@@ -119,7 +119,7 @@ ssb  rsa3072/0xCFDDC96F12B1915C
 | 
			
		||||
  the Calmares site or as part of a release announcement).
 | 
			
		||||
  - Send the updated key to keyservers with `gpg --send-keys <keyid>`
 | 
			
		||||
  - Optional: sanitize the keyring for use in development machines.
 | 
			
		||||
    Export the current subkeys of the master key and keep **only** those
 | 
			
		||||
    Export the current subkeys of the primary key and keep **only** those
 | 
			
		||||
    secret keys around. There is documentation
 | 
			
		||||
    [here](https://blog.tinned-software.net/create-gnupg-key-with-sub-keys-to-sign-encrypt-authenticate/)
 | 
			
		||||
    but be careful.
 | 
			
		||||
@@ -128,3 +128,18 @@ ssb  rsa3072/0xCFDDC96F12B1915C
 | 
			
		||||
  - Upload that public key to the relevant GitHub profile.
 | 
			
		||||
  - Upload that public key to the Calamares site.
 | 
			
		||||
 | 
			
		||||
## Placeholder Release Notes
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
# 3.2.XX (unreleased) #
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - No external contributors yet
 | 
			
		||||
 | 
			
		||||
## Core ##
 | 
			
		||||
 - No core changes yet
 | 
			
		||||
 | 
			
		||||
## Modules ##
 | 
			
		||||
 - No module changes yet
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -27,11 +27,13 @@
 | 
			
		||||
#   * `-B` do not build (before tagging)
 | 
			
		||||
#   * `-P` do not package (tag, sign, tarball)
 | 
			
		||||
#   * `-T` do not respect string freeze
 | 
			
		||||
#   * '-b' do not build-and-test tarball
 | 
			
		||||
#
 | 
			
		||||
# The build / package settings can be influenced via environment variables:
 | 
			
		||||
#   * BUILD_DEFAULT set to `false` to avoid first build with gcc
 | 
			
		||||
#   * BUILD_CLANG   set to `false` to avoid second build with clang
 | 
			
		||||
#   * BUILD_ONLY    set to `true` to break after building
 | 
			
		||||
#   * TEST_TARBALL  set to 'false' to skip build-and-test phase after tarring
 | 
			
		||||
#
 | 
			
		||||
### END USAGE
 | 
			
		||||
 | 
			
		||||
@@ -43,9 +45,10 @@ which cmake > /dev/null 2>&1 || { echo "No cmake(1) available." ; exit 1 ; }
 | 
			
		||||
test -z "$BUILD_DEFAULT" && BUILD_DEFAULT=true
 | 
			
		||||
test -z "$BUILD_CLANG" && BUILD_CLANG=true
 | 
			
		||||
test -z "$BUILD_ONLY" && BUILD_ONLY=false
 | 
			
		||||
test -z "$TEST_TARBALL" && TEST_TARBALL=true
 | 
			
		||||
STRING_FREEZE=true
 | 
			
		||||
 | 
			
		||||
while getopts "hBPT" opt ; do
 | 
			
		||||
while getopts "hBbPT" opt ; do
 | 
			
		||||
    case "$opt" in
 | 
			
		||||
    h|\?)
 | 
			
		||||
        sed -e '1,/USAGE/d' -e '/END.USAGE/,$d' < "$0"
 | 
			
		||||
@@ -55,6 +58,9 @@ while getopts "hBPT" opt ; do
 | 
			
		||||
        BUILD_DEFAULT=false
 | 
			
		||||
        BUILD_CLANG=false
 | 
			
		||||
        ;;
 | 
			
		||||
    b)
 | 
			
		||||
	TEST_TARBALL=false
 | 
			
		||||
	;;
 | 
			
		||||
    P)
 | 
			
		||||
        BUILD_ONLY=true
 | 
			
		||||
        ;;
 | 
			
		||||
@@ -72,7 +78,23 @@ fi
 | 
			
		||||
### Setup
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
BUILDDIR=$(mktemp -d --suffix=-build --tmpdir=.)
 | 
			
		||||
BUILDDIR=$(mktemp -d ./cala-tmp-XXXXXX)
 | 
			
		||||
KEY_ID="328D742D8807A435"
 | 
			
		||||
 | 
			
		||||
# Try to make gpg cache the signing key, so we can leave the process
 | 
			
		||||
# to run and sign.
 | 
			
		||||
rm -f CMakeLists.txt.gpg
 | 
			
		||||
gpg -s -u $KEY_ID CMakeLists.txt
 | 
			
		||||
 | 
			
		||||
### Get version number for this release
 | 
			
		||||
#
 | 
			
		||||
# Do this early, in a clean build-dir, since it doesn't cost much.
 | 
			
		||||
# Redirect stderr from CMake script mode, because the message()
 | 
			
		||||
# in CMakeLists.txt that prints the version, goes to stderr.
 | 
			
		||||
rm -rf "$BUILDDIR"
 | 
			
		||||
mkdir "$BUILDDIR" || { echo "Could not create build directory." ; exit 1 ; }
 | 
			
		||||
V=$( cd "$BUILDDIR" && cmake -P ../CMakeLists.txt 2>&1 )
 | 
			
		||||
test -n "$V" || { echo "Could not obtain version in $BUILDDIR ." ; exit 1 ; }
 | 
			
		||||
 | 
			
		||||
### Build with default compiler
 | 
			
		||||
#
 | 
			
		||||
@@ -112,17 +134,10 @@ else
 | 
			
		||||
    ( cd "$BUILDDIR" && cmake .. ) || { echo "Could not run cmake in $BUILDDIR ." ; exit 1 ; }
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
### Get version number for this release
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
V=$( cd "$BUILDDIR" && make show-version | grep ^CALAMARES_VERSION | sed s/^[A-Z_]*=// )
 | 
			
		||||
test -n "$V" || { echo "Could not obtain version in $BUILDDIR ." ; exit 1 ; }
 | 
			
		||||
 | 
			
		||||
### Create signed tag
 | 
			
		||||
#
 | 
			
		||||
# This is the signing key ID associated with the GitHub account adriaandegroot,
 | 
			
		||||
# which is used to create all "verified" tags in the Calamares repo.
 | 
			
		||||
KEY_ID="CFDDC96F12B1915C"
 | 
			
		||||
git tag -u "$KEY_ID" -m "Release v$V" "v$V" || { echo "Could not sign tag v$V." ; exit 1 ; }
 | 
			
		||||
 | 
			
		||||
### Create the tarball
 | 
			
		||||
@@ -137,12 +152,15 @@ SHA256=$(sha256sum "$TAR_FILE" | cut -d" " -f1)
 | 
			
		||||
### Build the tarball
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
D=$(date +%Y%m%d-%H%M%S)
 | 
			
		||||
TMPDIR=$(mktemp -d --suffix="-calamares-$D")
 | 
			
		||||
test -d "$TMPDIR" || { echo "Could not create tarball-build directory." ; exit 1 ; }
 | 
			
		||||
tar xzf "$TAR_FILE" -C "$TMPDIR" || { echo "Could not unpack tarball." ; exit 1 ; }
 | 
			
		||||
test -d "$TMPDIR/$TAR_V" || { echo "Tarball did not contain source directory." ; exit 1 ; }
 | 
			
		||||
( cd "$TMPDIR/$TAR_V" && cmake . && make -j4 && make test ) || { echo "Tarball build failed in $TMPDIR ." ; exit 1 ; }
 | 
			
		||||
if test "x$TEST_TARBALL" = "xtrue" ; then
 | 
			
		||||
    D=$(date +%Y%m%d-%H%M%S)
 | 
			
		||||
    TMPDIR=$(mktemp -d ./cala-tar-XXXXXX)
 | 
			
		||||
    test -d "$TMPDIR" || { echo "Could not create tarball-build directory." ; exit 1 ; }
 | 
			
		||||
    tar xzf "$TAR_FILE" -C "$TMPDIR" || { echo "Could not unpack tarball." ; exit 1 ; }
 | 
			
		||||
    test -d "$TMPDIR/$TAR_V" || { echo "Tarball did not contain source directory." ; exit 1 ; }
 | 
			
		||||
    ( cd "$TMPDIR/$TAR_V" && cmake . && make -j4 && make test ) || { echo "Tarball build failed in $TMPDIR ." ; exit 1 ; }
 | 
			
		||||
fi
 | 
			
		||||
gpg -s -u $KEY_ID --detach --armor $TAR_FILE  # Sign the tarball
 | 
			
		||||
 | 
			
		||||
### Cleanup
 | 
			
		||||
#
 | 
			
		||||
@@ -155,7 +173,6 @@ rm -rf "$TMPDIR"  # From tarball
 | 
			
		||||
cat <<EOF
 | 
			
		||||
# Next steps for this release:
 | 
			
		||||
  git push origin v$V
 | 
			
		||||
  gpg -s -u $KEY_ID --detach --armor $TAR_FILE  # Sign the tarball
 | 
			
		||||
  # Upload tarball $TAR_FILE and the signature $TAR_FILE.asc
 | 
			
		||||
  # Announce via https://github.com/calamares/calamares/releases/new
 | 
			
		||||
  # SHA256: $SHA256
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										74
									
								
								ci/abicheck.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										74
									
								
								ci/abicheck.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,74 @@
 | 
			
		||||
#! /bin/sh
 | 
			
		||||
#
 | 
			
		||||
# SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
 | 
			
		||||
# SPDX-License-Identifier: BSD-2-Clause
 | 
			
		||||
#
 | 
			
		||||
# Compares the ABI of the current working tree with the ABI
 | 
			
		||||
# from a base-version. Uses libabigail for the actual comparison.
 | 
			
		||||
#
 | 
			
		||||
# To use the tool, just run the script. It will build Calamares at
 | 
			
		||||
# least once, maybe twice (if it needs the base-version ABI information
 | 
			
		||||
# and hasn't cached it).
 | 
			
		||||
 | 
			
		||||
# The base version can be a tag or git-hash; it will be checked-out
 | 
			
		||||
# in a worktree.
 | 
			
		||||
#
 | 
			
		||||
# Note that the hash here now is 3.3-alpha1, when ABI
 | 
			
		||||
# compatibility was not expected much. From 3.3-beta,
 | 
			
		||||
# whenever that is, ABI compatibility should be more of a concern.
 | 
			
		||||
BASE_VERSION=0c794183936b6d916a109784829e605cc4582e9f
 | 
			
		||||
 | 
			
		||||
### Build a tree and cache the ABI info into ci/
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
do_build() {
 | 
			
		||||
	LABEL=$1
 | 
			
		||||
	SOURCE_DIR=$2
 | 
			
		||||
 | 
			
		||||
	BUILD_DIR=build-abi-$LABEL
 | 
			
		||||
	rm -rf $BUILD_DIR
 | 
			
		||||
	mkdir $BUILD_DIR
 | 
			
		||||
 | 
			
		||||
	if ( cd $BUILD_DIR && cmake $SOURCE_DIR -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="-Og -g -gdwarf" -DCMAKE_C_FLAGS="-Og -g -gdwarf" && make -j12 ) > /dev/null 2>&1
 | 
			
		||||
	then
 | 
			
		||||
		ls -1 $BUILD_DIR/libcalamares*.so.*
 | 
			
		||||
		# Copy the un-versioned files; .so is a symlink to the just-built one
 | 
			
		||||
		for lib in $BUILD_DIR/libcalamares*.so
 | 
			
		||||
		do
 | 
			
		||||
			cp $lib ci/`basename $lib`.$LABEL
 | 
			
		||||
		done
 | 
			
		||||
	else
 | 
			
		||||
		echo "! failed to build $LABEL"
 | 
			
		||||
		exit 1
 | 
			
		||||
	fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
### Build current tree and get ABI info
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
do_build current `pwd -P`
 | 
			
		||||
 | 
			
		||||
### Build ABI base version
 | 
			
		||||
#
 | 
			
		||||
# We cache this to save on some build time, if we are chasing a
 | 
			
		||||
# single branch from an unchanging base version.
 | 
			
		||||
#
 | 
			
		||||
if test -f ci/libcalamares.so.$BASE_VERSION
 | 
			
		||||
then
 | 
			
		||||
	# The ABI version is cached, so we're good
 | 
			
		||||
	:
 | 
			
		||||
else
 | 
			
		||||
	git worktree remove --force tree-abi-$BASE_VERSION
 | 
			
		||||
	git worktree add tree-abi-$BASE_VERSION $BASE_VERSION > /dev/null 2>&1 || { echo "! could not create worktree for $BASE_VERSION" ; exit 1 ; }
 | 
			
		||||
	do_build $BASE_VERSION $( cd tree-abi-$BASE_VERSION && pwd -P )
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
### Compare & Report
 | 
			
		||||
#
 | 
			
		||||
# abidiff compares the Application Binary Interfaces (ABI) of two
 | 
			
		||||
# shared libraries in ELF format. It emits a meaningful report describing
 | 
			
		||||
# the differences between the two ABIs.
 | 
			
		||||
#
 | 
			
		||||
# -l prints only the leaf changes, leaving out explanations of why.
 | 
			
		||||
#
 | 
			
		||||
abidiff -l ci/libcalamares.so.$BASE_VERSION ci/libcalamares.so.current
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user