Compare commits
	
		
			1043 Commits
		
	
	
		
			v3.2.56
			...
			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 | ||
| 
						 | 
					dcbb83ebe5 | ||
| 
						 | 
					73d09977fc | ||
| 
						 | 
					47016765b3 | ||
| 
						 | 
					217e4ab4f7 | ||
| 
						 | 
					b129cb0786 | ||
| 
						 | 
					e102e2630e | ||
| 
						 | 
					7650795f48 | ||
| 
						 | 
					e5036da084 | ||
| 
						 | 
					07f4ec529b | ||
| 
						 | 
					0b2af86ec9 | ||
| 
						 | 
					8b917ace4d | ||
| 
						 | 
					ab1c78ca23 | ||
| 
						 | 
					3679bb45f0 | ||
| 
						 | 
					1101b0dc82 | ||
| 
						 | 
					15b4660d3e | ||
| 
						 | 
					e457d099d8 | ||
| 
						 | 
					7686b89cd6 | ||
| 
						 | 
					e757639669 | ||
| 
						 | 
					7b22546b14 | ||
| 
						 | 
					7db14cb5cf | ||
| 
						 | 
					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 | ||
| 
						 | 
					f6b65b3b93 | ||
| 
						 | 
					bbea67ecb4 | ||
| 
						 | 
					d76dd2f8e0 | ||
| 
						 | 
					334b7fc219 | ||
| 
						 | 
					f923dedc3f | ||
| 
						 | 
					576f244d2d | ||
| 
						 | 
					d03a8acc9d | ||
| 
						 | 
					2c0d9396e2 | ||
| 
						 | 
					bb278c7ba9 | ||
| 
						 | 
					3bf0a93b86 | ||
| 
						 | 
					82b5ca8bfc | ||
| 
						 | 
					f64938cb3f | ||
| 
						 | 
					9b0ef5fce5 | ||
| 
						 | 
					8ce92d450c | ||
| 
						 | 
					982f9c8458 | ||
| 
						 | 
					f888cb87d1 | ||
| 
						 | 
					97031ea3e6 | ||
| 
						 | 
					a303efb174 | ||
| 
						 | 
					029bb3efdd | ||
| 
						 | 
					4545470f2d | ||
| 
						 | 
					99b19b9539 | ||
| 
						 | 
					aedb55ea36 | ||
| 
						 | 
					49c56add7d | ||
| 
						 | 
					827d06df85 | ||
| 
						 | 
					107afcff27 | ||
| 
						 | 
					1793c627cd | ||
| 
						 | 
					03291fb726 | ||
| 
						 | 
					0be88f1453 | ||
| 
						 | 
					a59c45d869 | ||
| 
						 | 
					7f14aa6bf1 | ||
| 
						 | 
					c7cc599a19 | ||
| 
						 | 
					3b55c2805a | ||
| 
						 | 
					cf097850de | ||
| 
						 | 
					b167d8da03 | ||
| 
						 | 
					e507a23795 | ||
| 
						 | 
					5160fdc26a | ||
| 
						 | 
					8f769006d6 | ||
| 
						 | 
					d98027ad2f | ||
| 
						 | 
					2bf43ffbf2 | ||
| 
						 | 
					0c7f06137a | ||
| 
						 | 
					a352bd946e | ||
| 
						 | 
					d1e4740e70 | ||
| 
						 | 
					5b483ab26f | ||
| 
						 | 
					3e1bc6cb22 | ||
| 
						 | 
					bb1d3022e0 | ||
| 
						 | 
					a50ffa74e1 | ||
| 
						 | 
					03f2e45605 | ||
| 
						 | 
					24a881ad75 | ||
| 
						 | 
					e4a3b66024 | ||
| 
						 | 
					1667d75a70 | ||
| 
						 | 
					ce23efae99 | ||
| 
						 | 
					bd4bed1438 | ||
| 
						 | 
					23f6b25cfc | ||
| 
						 | 
					8e959105c6 | ||
| 
						 | 
					dde55471ba | ||
| 
						 | 
					97eea9bde2 | ||
| 
						 | 
					b5f8e30093 | ||
| 
						 | 
					9d9cd44617 | ||
| 
						 | 
					c1f7a2c855 | ||
| 
						 | 
					e0f40cb4a4 | ||
| 
						 | 
					04e927e67f | ||
| 
						 | 
					605ad788d0 | ||
| 
						 | 
					bcde8b87b1 | ||
| 
						 | 
					cb3b2422a9 | ||
| 
						 | 
					60cc8696e3 | ||
| 
						 | 
					ca4dbabf70 | ||
| 
						 | 
					c1e1e6c3a4 | ||
| 
						 | 
					cf6c930df5 | ||
| 
						 | 
					e1df2a2450 | ||
| 
						 | 
					bd3f89fb57 | ||
| 
						 | 
					f9dc932f62 | ||
| 
						 | 
					4b08aebe7f | ||
| 
						 | 
					1fe27effe5 | ||
| 
						 | 
					453e760709 | ||
| 
						 | 
					0ad9242ab7 | ||
| 
						 | 
					5da736466c | ||
| 
						 | 
					df256b608a | ||
| 
						 | 
					1f5bdef96e | ||
| 
						 | 
					261c3587a5 | ||
| 
						 | 
					a6ba3dfce0 | ||
| 
						 | 
					1bd5628256 | ||
| 
						 | 
					714605ebaa | ||
| 
						 | 
					5975ff9e42 | ||
| 
						 | 
					a27b72e893 | ||
| 
						 | 
					396746acc1 | ||
| 
						 | 
					adc3af0345 | ||
| 
						 | 
					5a82c8123b | ||
| 
						 | 
					8ab1a4fb30 | ||
| 
						 | 
					72701aae21 | ||
| 
						 | 
					419be4df25 | 
@@ -22,6 +22,7 @@ Cpp11BracedListStyle: "false"
 | 
			
		||||
FixNamespaceComments: "true"
 | 
			
		||||
IncludeBlocks: Preserve
 | 
			
		||||
IndentWidth: "4"
 | 
			
		||||
InsertBraces: "true"
 | 
			
		||||
MaxEmptyLinesToKeep: "2"
 | 
			
		||||
NamespaceIndentation: None
 | 
			
		||||
PointerAlignment: Left
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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
 | 
			
		||||
							
								
								
									
										14
									
								
								.github/workflows/issues.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								.github/workflows/issues.yml
									
									
									
									
										vendored
									
									
								
							@@ -8,20 +8,6 @@ jobs:
 | 
			
		||||
  notify:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: "notify: new"
 | 
			
		||||
        if: github.event.issue.state == 'open'
 | 
			
		||||
        uses: calamares/actions/matrix-notify@v4
 | 
			
		||||
        with:
 | 
			
		||||
          token: ${{ secrets.MATRIX_TOKEN }}
 | 
			
		||||
          room: ${{ secrets.MATRIX_ROOM }}
 | 
			
		||||
          message: "OPENED ${{ github.event.issue.html_url }} by ${{ github.actor }} ${{ github.event.issue.title }}"
 | 
			
		||||
      - name: "notify: closed"
 | 
			
		||||
        if: github.event.issue.state != 'open'
 | 
			
		||||
        uses: calamares/actions/matrix-notify@v4
 | 
			
		||||
        with:
 | 
			
		||||
          token: ${{ secrets.MATRIX_TOKEN }}
 | 
			
		||||
          room: ${{ secrets.MATRIX_ROOM }}
 | 
			
		||||
          message: "CLOSED ${{ github.event.issue.html_url }} by ${{ github.actor }} ${{ github.event.issue.title }}"
 | 
			
		||||
      - name: "remove in-progress label"
 | 
			
		||||
        if: github.event.issue.state != 'open'
 | 
			
		||||
        run: |
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										36
									
								
								.github/workflows/nightly-debian.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										36
									
								
								.github/workflows/nightly-debian.yml
									
									
									
									
										vendored
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
name: nightly-debian-10
 | 
			
		||||
name: nightly-debian-11
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  schedule:
 | 
			
		||||
@@ -9,36 +9,26 @@ 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
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  build:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    container:
 | 
			
		||||
      image: docker://debian:10
 | 
			
		||||
      image: docker://debian:11
 | 
			
		||||
      options: --tmpfs /build:rw --user 0:0
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: "prepare env"
 | 
			
		||||
        uses: calamares/actions/prepare-debian@v4
 | 
			
		||||
      - 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@v4
 | 
			
		||||
        uses: calamares/actions/generic-checkout@v5
 | 
			
		||||
      - name: "install dependencies"
 | 
			
		||||
        shell: bash
 | 
			
		||||
        run: ./ci/deps-debian11.sh
 | 
			
		||||
      - name: "build"
 | 
			
		||||
        id: build
 | 
			
		||||
        uses: calamares/actions/generic-build@v4
 | 
			
		||||
      - name: "notify: ok"
 | 
			
		||||
        if: ${{ success() && github.repository == 'calamares/calamares' }}
 | 
			
		||||
        uses: calamares/actions/matrix-notify@v4
 | 
			
		||||
        with:
 | 
			
		||||
          token: ${{ secrets.MATRIX_TOKEN }}
 | 
			
		||||
          room: ${{ secrets.MATRIX_ROOM }}
 | 
			
		||||
          message: "OK ${{ github.workflow }} in ${{ github.repository }} ${{ steps.build.outputs.git-summary }}"
 | 
			
		||||
      - name: "notify: fail"
 | 
			
		||||
        if: ${{ failure() && github.repository == 'calamares/calamares' }}
 | 
			
		||||
        uses: calamares/actions/matrix-notify@v4
 | 
			
		||||
        with:
 | 
			
		||||
          token: ${{ secrets.MATRIX_TOKEN }}
 | 
			
		||||
          room: ${{ secrets.MATRIX_ROOM }}
 | 
			
		||||
          message: "FAIL ${{ github.workflow }} in ${{ github.repository }} ${{ steps.build.outputs.git-summary }}"
 | 
			
		||||
        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
 | 
			
		||||
							
								
								
									
										33
									
								
								.github/workflows/nightly-neon.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										33
									
								
								.github/workflows/nightly-neon.yml
									
									
									
									
										vendored
									
									
								
							@@ -9,9 +9,7 @@ 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
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
@@ -21,36 +19,23 @@ jobs:
 | 
			
		||||
      image: docker://kdeneon/plasma:user
 | 
			
		||||
      options: --tmpfs /build:rw --user 0:0
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: "prepare env"
 | 
			
		||||
        uses: calamares/actions/prepare-neon@v4
 | 
			
		||||
      - name: "prepare source"
 | 
			
		||||
        uses: calamares/actions/generic-checkout@v4
 | 
			
		||||
        uses: calamares/actions/generic-checkout@v5
 | 
			
		||||
      - name: "install dependencies"
 | 
			
		||||
        shell: bash
 | 
			
		||||
        run: ./ci/deps-neon.sh
 | 
			
		||||
      - name: "build"
 | 
			
		||||
        id: build
 | 
			
		||||
        uses: calamares/actions/generic-build@v4
 | 
			
		||||
        shell: bash
 | 
			
		||||
        run: ./ci/build.sh
 | 
			
		||||
      - name: "Calamares: archive"
 | 
			
		||||
        working-directory: ${{ env.BUILDDIR }}
 | 
			
		||||
        run: |
 | 
			
		||||
          make install DESTDIR=${{ env.BUILDDIR }}/stage
 | 
			
		||||
          DESTDIR=${{ env.BUILDDIR }}/stage ninja install
 | 
			
		||||
          tar czf calamares.tar.gz stage
 | 
			
		||||
      - name: "Calamares: upload"
 | 
			
		||||
        uses: actions/upload-artifact@v2
 | 
			
		||||
        uses: actions/upload-artifact@v3
 | 
			
		||||
        with:
 | 
			
		||||
          name: calamares-tarball
 | 
			
		||||
          path: ${{ env.BUILDDIR }}/calamares.tar.gz
 | 
			
		||||
          if-no-files-found: error
 | 
			
		||||
          retention-days: 3
 | 
			
		||||
      - name: "notify: ok"
 | 
			
		||||
        if: ${{ success() && github.repository == 'calamares/calamares' }}
 | 
			
		||||
        uses: calamares/actions/matrix-notify@v4
 | 
			
		||||
        with:
 | 
			
		||||
          token: ${{ secrets.MATRIX_TOKEN }}
 | 
			
		||||
          room: ${{ secrets.MATRIX_ROOM }}
 | 
			
		||||
          message: "OK ${{ github.workflow }} in ${{ github.repository }} ${{ steps.build.outputs.git-summary }}"
 | 
			
		||||
      - name: "notify: fail"
 | 
			
		||||
        if: ${{ failure() && github.repository == 'calamares/calamares' }}
 | 
			
		||||
        uses: calamares/actions/matrix-notify@v4
 | 
			
		||||
        with:
 | 
			
		||||
          token: ${{ secrets.MATRIX_TOKEN }}
 | 
			
		||||
          room: ${{ secrets.MATRIX_ROOM }}
 | 
			
		||||
          message: "FAIL ${{ github.workflow }} in ${{ github.repository }} ${{ steps.build.outputs.git-summary }}"
 | 
			
		||||
          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
 | 
			
		||||
							
								
								
									
										35
									
								
								.github/workflows/nightly-opensuse.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										35
									
								
								.github/workflows/nightly-opensuse.yml
									
									
									
									
										vendored
									
									
								
							@@ -9,37 +9,26 @@ 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
 | 
			
		||||
    -DBUILD_SCHEMA_TESTING=ON
 | 
			
		||||
    -DBUILD_TESTING=ON
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  build:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    container:
 | 
			
		||||
      image: docker://opensuse/leap
 | 
			
		||||
      image: docker://opensuse/tumbleweed
 | 
			
		||||
      options: --tmpfs /build:rw --user 0:0
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: "prepare env"
 | 
			
		||||
        uses: calamares/actions/prepare-opensuse@v4
 | 
			
		||||
      - name: "prepare git"
 | 
			
		||||
        shell: bash
 | 
			
		||||
        run: zypper --non-interactive in git-core jq curl
 | 
			
		||||
      - name: "prepare source"
 | 
			
		||||
        uses: calamares/actions/generic-checkout@v4
 | 
			
		||||
        uses: calamares/actions/generic-checkout@v5
 | 
			
		||||
      - name: "install dependencies"
 | 
			
		||||
        shell: bash
 | 
			
		||||
        run: ./ci/deps-opensuse.sh
 | 
			
		||||
      - name: "build"
 | 
			
		||||
        id: build
 | 
			
		||||
        uses: calamares/actions/generic-build@v4
 | 
			
		||||
      - name: "notify: ok"
 | 
			
		||||
        if: ${{ success() && github.repository == 'calamares/calamares' }}
 | 
			
		||||
        uses: calamares/actions/matrix-notify@v4
 | 
			
		||||
        with:
 | 
			
		||||
          token: ${{ secrets.MATRIX_TOKEN }}
 | 
			
		||||
          room: ${{ secrets.MATRIX_ROOM }}
 | 
			
		||||
          message: |
 | 
			
		||||
            OK ${{ github.workflow }} in ${{ github.repository }} ${{ steps.build.outputs.git-summary }}"
 | 
			
		||||
      - name: "notify: fail"
 | 
			
		||||
        if: ${{ failure() && github.repository == 'calamares/calamares' }}
 | 
			
		||||
        uses: calamares/actions/matrix-notify@v4
 | 
			
		||||
        with:
 | 
			
		||||
          token: ${{ secrets.MATRIX_TOKEN }}
 | 
			
		||||
          room: ${{ secrets.MATRIX_ROOM }}
 | 
			
		||||
          message: "FAIL ${{ github.workflow }} in ${{ github.repository }} ${{ steps.build.outputs.git-summary }}"
 | 
			
		||||
        shell: bash
 | 
			
		||||
        run: ./ci/build.sh
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										34
									
								
								.github/workflows/push.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										34
									
								
								.github/workflows/push.yml
									
									
									
									
										vendored
									
									
								
							@@ -4,7 +4,6 @@ on:
 | 
			
		||||
  push:
 | 
			
		||||
    branches:
 | 
			
		||||
      - calamares
 | 
			
		||||
      - work-3.3
 | 
			
		||||
  pull_request:
 | 
			
		||||
    types:
 | 
			
		||||
      - opened
 | 
			
		||||
@@ -18,8 +17,9 @@ env:
 | 
			
		||||
  CMAKE_ARGS: |
 | 
			
		||||
    -DWEBVIEW_FORCE_WEBKIT=1
 | 
			
		||||
    -DKDE_INSTALL_USE_QT_SYS_PATHS=ON
 | 
			
		||||
    -DWITH_PYTHONQT=OFF"
 | 
			
		||||
    -DWITH_PYTHONQT=OFF
 | 
			
		||||
    -DCMAKE_BUILD_TYPE=Debug
 | 
			
		||||
  GIT_HASH: ${{ github.event.head_commit.id }}
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  build:
 | 
			
		||||
@@ -28,29 +28,11 @@ jobs:
 | 
			
		||||
      image: docker://kdeneon/plasma:user
 | 
			
		||||
      options: --tmpfs /build:rw --user 0:0
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: "prepare env"
 | 
			
		||||
        uses: calamares/actions/prepare-neon@v4
 | 
			
		||||
      - name: "prepare source"
 | 
			
		||||
        uses: calamares/actions/generic-checkout@v4
 | 
			
		||||
        uses: calamares/actions/generic-checkout@v5
 | 
			
		||||
      - name: "install dependencies"
 | 
			
		||||
        shell: bash
 | 
			
		||||
        run: ./ci/deps-neon.sh
 | 
			
		||||
      - name: "build"
 | 
			
		||||
        id: build
 | 
			
		||||
        uses: calamares/actions/generic-build@v4
 | 
			
		||||
      - name: "notify: ok"
 | 
			
		||||
        if: ${{ success() && github.repository == 'calamares/calamares' }}
 | 
			
		||||
        uses: calamares/actions/matrix-notify@v4
 | 
			
		||||
        with:
 | 
			
		||||
          token: ${{ secrets.MATRIX_TOKEN }}
 | 
			
		||||
          room: ${{ secrets.MATRIX_ROOM }}
 | 
			
		||||
          message: |
 | 
			
		||||
            OK ${{ github.workflow }} in ${{ github.repository }} by ${{ github.actor }} on ${{ github.event.ref }}
 | 
			
		||||
            .. ${{ steps.build.outputs.git-summary }}
 | 
			
		||||
      - name: "notify: fail"
 | 
			
		||||
        if: ${{ failure() && github.repository == 'calamares/calamares' }}
 | 
			
		||||
        uses: calamares/actions/matrix-notify@v4
 | 
			
		||||
        with:
 | 
			
		||||
          token: ${{ secrets.MATRIX_TOKEN }}
 | 
			
		||||
          room: ${{ secrets.MATRIX_ROOM }}
 | 
			
		||||
          message: |
 | 
			
		||||
            FAIL ${{ github.workflow }} in ${{ github.repository }} by ${{ github.actor }} on ${{ github.event.ref }}
 | 
			
		||||
              .. ${{ steps.build.outputs.git-summary }}
 | 
			
		||||
              .. ${{ github.event.compare }}
 | 
			
		||||
        shell: bash
 | 
			
		||||
        run: ./ci/build.sh
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										18
									
								
								.reuse/dep5
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								.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
 | 
			
		||||
@@ -50,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
 | 
			
		||||
@@ -81,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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										30
									
								
								AUTHORS
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								AUTHORS
									
									
									
									
									
								
							@@ -20,30 +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
 | 
			
		||||
 - Neal Gompa
 | 
			
		||||
 - 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.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										152
									
								
								CHANGES-3.2
									
									
									
									
									
								
							
							
						
						
									
										152
									
								
								CHANGES-3.2
									
									
									
									
									
								
							@@ -1,4 +1,3 @@
 | 
			
		||||
 | 
			
		||||
<!-- SPDX-FileCopyrightText: no
 | 
			
		||||
     SPDX-License-Identifier: CC0-1.0
 | 
			
		||||
-->
 | 
			
		||||
@@ -8,6 +7,157 @@ 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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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 `@@`.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										698
									
								
								CMakeLists.txt
									
									
									
									
									
								
							
							
						
						
									
										698
									
								
								CMakeLists.txt
									
									
									
									
									
								
							@@ -19,54 +19,78 @@
 | 
			
		||||
#
 | 
			
		||||
#   SKIP_MODULES    : a space or semicolon-separated list of directory names
 | 
			
		||||
#                     under src/modules that should not be built.
 | 
			
		||||
#   USE_<foo>       : fills in SKIP_MODULES for modules called <foo>-<something>
 | 
			
		||||
#   USE_<foo>       : fills in SKIP_MODULES for modules called <foo>-<something>.
 | 
			
		||||
#   WITH_<foo>      : try to enable <foo> (these usually default to ON). For
 | 
			
		||||
#                     a list of WITH_<foo> grep CMakeCache.txt after running
 | 
			
		||||
#                     CMake once. These affect the ABI offered by Calamares.
 | 
			
		||||
#                       - PYTHON (enable Python Job modules)
 | 
			
		||||
#                       - QML (enable QML UI View modules)
 | 
			
		||||
#                       - PYTHONQT # TODO:3.3: remove
 | 
			
		||||
#                       - PYBIND11 (use bundled pybind11, default ON, needs WITH_PYTHON)
 | 
			
		||||
#                       - PYTHON (enable Python Job modules, default ON if Python is found)
 | 
			
		||||
#                       - QML (enable QML UI View modules, default ON)
 | 
			
		||||
#                       - QT6 (use Qt6 rather than Qt5, default to OFF)
 | 
			
		||||
#                     The WITH_* options affect the ABI of Calamares: you must
 | 
			
		||||
#                     build (C++) modules for Calamares with the same WITH_*
 | 
			
		||||
#                     settings, or they may not load at all.
 | 
			
		||||
#   BUILD_<foo>     : choose additional things to build
 | 
			
		||||
#                       - TESTING (standard CMake option)
 | 
			
		||||
#                       - APPDATA (use AppData in packagechooser, requires QtXml)
 | 
			
		||||
#                       - APPSTREAM (use AppStream in packagechooser, requires libappstream-qt)
 | 
			
		||||
#                       - BUILD_CRASH_REPORTING (uses KCrash, rather than Calamares internal, for crash reporting)
 | 
			
		||||
#                       - SCHEMA_TESTING (requires Python, see ci/configvalidator.py)
 | 
			
		||||
#   DEBUG_<foo>     : special developer flags for debugging
 | 
			
		||||
#                       - TESTING (standard CMake option)
 | 
			
		||||
#   DEBUG_<foo>     : special developer flags for debugging.
 | 
			
		||||
#
 | 
			
		||||
# Example usage:
 | 
			
		||||
#
 | 
			
		||||
#   cmake . -DSKIP_MODULES="partition luksbootkeycfg"
 | 
			
		||||
#
 | 
			
		||||
# One special target is "show-version", which can be built
 | 
			
		||||
# to obtain the version number from here.
 | 
			
		||||
# To obtain the version number of calamares, run CMake in script mode, e.g.
 | 
			
		||||
#   cmake -P CMakeLists.txt
 | 
			
		||||
 | 
			
		||||
# TODO:3.3: Require CMake 3.12
 | 
			
		||||
cmake_minimum_required( VERSION 3.3 FATAL_ERROR )
 | 
			
		||||
project( CALAMARES
 | 
			
		||||
    VERSION 3.2.56
 | 
			
		||||
    LANGUAGES C CXX
 | 
			
		||||
)
 | 
			
		||||
cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
 | 
			
		||||
 | 
			
		||||
set( CALAMARES_VERSION_RC 0 )  # Set to 0 during release cycle, 1 during development
 | 
			
		||||
if( CALAMARES_VERSION_RC EQUAL 1 AND CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR )
 | 
			
		||||
    message( FATAL_ERROR "Do not build development versions in the source-directory." )
 | 
			
		||||
set(CALAMARES_VERSION 3.3.1)
 | 
			
		||||
set(CALAMARES_RELEASE_MODE OFF) # Set to ON during a release
 | 
			
		||||
 | 
			
		||||
if(CMAKE_SCRIPT_MODE_FILE)
 | 
			
		||||
    include(${CMAKE_CURRENT_LIST_DIR}/CMakeModules/ExtendedVersion.cmake)
 | 
			
		||||
    set(CMAKE_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR})
 | 
			
		||||
    extend_version( ${CALAMARES_VERSION} ${CALAMARES_RELEASE_MODE}  _vshort _vlong )
 | 
			
		||||
    message("${_vlong}")
 | 
			
		||||
    return()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
# Massage the version for CMake if there is a version-suffix
 | 
			
		||||
string(REGEX REPLACE "-.*" "" CALAMARES_VERSION_SHORT "${CALAMARES_VERSION}")
 | 
			
		||||
# And preserve the original version (suffix and all) because project() overwrites
 | 
			
		||||
# .. but if we're doing non-release builds, this gets replaced with git versioning.
 | 
			
		||||
set(CALAMARES_VERSION_LONG "${CALAMARES_VERSION}")
 | 
			
		||||
 | 
			
		||||
project(CALAMARES VERSION ${CALAMARES_VERSION_SHORT} LANGUAGES C CXX HOMEPAGE_URL "https://calamares.io/")
 | 
			
		||||
 | 
			
		||||
if(NOT CALAMARES_RELEASE_MODE AND CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
 | 
			
		||||
    message(FATAL_ERROR "Do not build development versions in the source-directory.")
 | 
			
		||||
endif()
 | 
			
		||||
# Calamares in the 3.3 series promises ABI compatbility, so it sets a
 | 
			
		||||
# .so-version equal to the series number. We use ci/abicheck.sh to
 | 
			
		||||
# keep track of this. Note that the **alpha** releases also have
 | 
			
		||||
# such an .so-version, but are not ABI-stable yet.
 | 
			
		||||
set(CALAMARES_SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}")
 | 
			
		||||
 | 
			
		||||
### OPTIONS
 | 
			
		||||
#
 | 
			
		||||
option( INSTALL_CONFIG "Install configuration files" OFF )
 | 
			
		||||
option( INSTALL_POLKIT "Install Polkit configuration" ON )
 | 
			
		||||
option( INSTALL_COMPLETION "Install shell completions" OFF )
 | 
			
		||||
# Options for the calamares executable
 | 
			
		||||
option( WITH_KF5Crash "Enable crash reporting with KCrash." ON )  # TODO:3.3: WITH->BUILD (this isn't an ABI thing)
 | 
			
		||||
option( WITH_KF5DBus "Use DBus service for unique-application." OFF )  # TODO:3.3: WITH->BUILD
 | 
			
		||||
option(INSTALL_POLKIT "Install Polkit configuration" ON)
 | 
			
		||||
option(INSTALL_COMPLETION "Install shell completions" OFF)
 | 
			
		||||
option(INSTALL_CONFIG "Install configuration files" OFF)
 | 
			
		||||
# When adding WITH_* that affects the ABI offered by libcalamares,
 | 
			
		||||
# also update libcalamares/CalamaresConfig.h.in
 | 
			
		||||
option( WITH_PYTHON "Enable Python modules API (requires Boost.Python)." ON )
 | 
			
		||||
option( WITH_PYTHONQT "Enable Python view modules API (deprecated, requires PythonQt)." OFF )  # TODO:3.3: remove
 | 
			
		||||
option( WITH_QML "Enable QML UI options." ON )
 | 
			
		||||
option(WITH_PYBIND11 "Use bundled pybind11 instead o Boost::Python" ON)
 | 
			
		||||
option(WITH_PYTHON "Enable Python modules API." ON)
 | 
			
		||||
option(WITH_QML "Enable QML UI options." ON)
 | 
			
		||||
option(WITH_QT6 "Use Qt6 instead of Qt5" OFF)
 | 
			
		||||
#
 | 
			
		||||
# Additional parts to build
 | 
			
		||||
option( BUILD_SCHEMA_TESTING "Enable schema-validation-tests" ON )
 | 
			
		||||
 | 
			
		||||
# Additional parts to build that do not affect ABI
 | 
			
		||||
option(BUILD_SCHEMA_TESTING "Enable schema-validation-tests" ON)
 | 
			
		||||
# Options for the calamares executable
 | 
			
		||||
option(BUILD_CRASH_REPORTING "Enable crash reporting with KCrash." ON)
 | 
			
		||||
 | 
			
		||||
# Possible debugging flags are:
 | 
			
		||||
#  - DEBUG_TIMEZONES draws latitude and longitude lines on the timezone
 | 
			
		||||
@@ -77,7 +101,6 @@ option( BUILD_SCHEMA_TESTING "Enable schema-validation-tests" ON )
 | 
			
		||||
#  - DEBUG_PARTITION_UNSAFE (see partition/CMakeLists.txt)
 | 
			
		||||
#  - DEBUG_PARTITION_BAIL_OUT (see partition/CMakeLists.txt)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### USE_*
 | 
			
		||||
#
 | 
			
		||||
# By convention, when there are multiple modules that implement similar
 | 
			
		||||
@@ -101,15 +124,14 @@ option( BUILD_SCHEMA_TESTING "Enable schema-validation-tests" ON )
 | 
			
		||||
#  - *services* picks one of the two service-configuration modules,
 | 
			
		||||
#    for either systemd or openrc. This defaults to empty so that
 | 
			
		||||
#    **both** modules are available.
 | 
			
		||||
set( USE_services "" CACHE STRING "Select the services module to use" )
 | 
			
		||||
set(USE_services "" CACHE STRING "Select the services module to use")
 | 
			
		||||
 | 
			
		||||
### Calamares application info
 | 
			
		||||
#
 | 
			
		||||
set( CALAMARES_ORGANIZATION_NAME "Calamares" )
 | 
			
		||||
set( CALAMARES_ORGANIZATION_DOMAIN "github.com/calamares" )
 | 
			
		||||
set( CALAMARES_APPLICATION_NAME  "Calamares" )
 | 
			
		||||
set( CALAMARES_DESCRIPTION_SUMMARY
 | 
			
		||||
    "The distribution-independent installer framework" )
 | 
			
		||||
set(CALAMARES_ORGANIZATION_NAME "Calamares")
 | 
			
		||||
set(CALAMARES_ORGANIZATION_DOMAIN "github.com/calamares")
 | 
			
		||||
set(CALAMARES_APPLICATION_NAME "Calamares")
 | 
			
		||||
set(CALAMARES_DESCRIPTION_SUMMARY "The distribution-independent installer framework")
 | 
			
		||||
 | 
			
		||||
### Transifex (languages) info
 | 
			
		||||
#
 | 
			
		||||
@@ -120,54 +142,77 @@ set( CALAMARES_DESCRIPTION_SUMMARY
 | 
			
		||||
#
 | 
			
		||||
# Language en (source language) is added later. It isn't listed in
 | 
			
		||||
# Transifex either. Get the list of languages and their status
 | 
			
		||||
# from https://transifex.com/calamares/calamares/ , or (preferably)
 | 
			
		||||
# from https://app.transifex.com/calamares/calamares/ , or (preferably)
 | 
			
		||||
# use ci/txstats.py to automatically check.
 | 
			
		||||
#
 | 
			
		||||
# When adding a new language, take care that it is properly loaded
 | 
			
		||||
# by the translation framework. Languages with alternate scripts
 | 
			
		||||
# (sr@latin in particular) may need special handling in CalamaresUtils.cpp.
 | 
			
		||||
# (sr@latin in particular) or location (ca@valencia) need special
 | 
			
		||||
# handling in libcalamares/locale/Translation.h .
 | 
			
		||||
#
 | 
			
		||||
# NOTE: move eo (Esperanto) to _ok once Qt can actually create a
 | 
			
		||||
#       locale for it. (Qt 5.12.2 can, see Translation Status section).
 | 
			
		||||
# NOTE: move ie (Interlingue) to _ok once Qt supports it.
 | 
			
		||||
# NOTE: update these lines by running `txstats.py`, or for full automation
 | 
			
		||||
#       `txstats.py -e`. See also
 | 
			
		||||
#
 | 
			
		||||
# Total 74 languages
 | 
			
		||||
set( _tx_complete az az_AZ ca es fi_FI he hi hr ja lt pt_BR pt_PT
 | 
			
		||||
    sq sv uk zh_TW )
 | 
			
		||||
set( _tx_good as be ca@valencia cs_CZ da de fa fr fur it_IT ko ml
 | 
			
		||||
    nl ru si sk tg tr_TR vi zh_CN )
 | 
			
		||||
set( _tx_ok ar ast bg bn el en_GB es_MX et eu gl hu id is mr nb oc
 | 
			
		||||
    pl ro sl sr sr@latin th )
 | 
			
		||||
set( _tx_incomplete eo es_PR gu ie ja-Hira kk kn lo lv mk ne_NP
 | 
			
		||||
    ta_IN te ur zh zh_HK )
 | 
			
		||||
# Total 80 languages
 | 
			
		||||
set( _tx_complete az_AZ ca en es fi_FI fr he hr ja lt pl sq sv
 | 
			
		||||
    tr_TR uk zh_TW )
 | 
			
		||||
set( _tx_good as az be bg ca@valencia cs_CZ da de fa fur hi is
 | 
			
		||||
    it_IT ko nl pt_BR pt_PT ru si sk tg vi zh_CN )
 | 
			
		||||
set( _tx_ok ar ast bn el en_GB eo es_AR es_MX et eu gl hu id ml mr
 | 
			
		||||
    nb oc ro sl sr sr@latin th )
 | 
			
		||||
set( _tx_incomplete bqi es_PR gu ie ja-Hira ka kk kn lo lv mk ne_NP
 | 
			
		||||
    ro_RO ta_IN te ur uz zh zh_HK )
 | 
			
		||||
# Total 80 languages
 | 
			
		||||
 | 
			
		||||
### Required versions
 | 
			
		||||
#
 | 
			
		||||
# See DEPENDENCIES section below.
 | 
			
		||||
set( QT_VERSION 5.9.0 )
 | 
			
		||||
set( YAMLCPP_VERSION 0.5.1 )
 | 
			
		||||
set( ECM_VERSION 5.18 )
 | 
			
		||||
set( PYTHONLIBS_VERSION 3.3 )
 | 
			
		||||
set( BOOSTPYTHON_VERSION 1.55.0 )
 | 
			
		||||
if(WITH_QT6)
 | 
			
		||||
    message(STATUS "Building Calamares with Qt6")
 | 
			
		||||
    set(qtname "Qt6")
 | 
			
		||||
    set(kfname "KF6")
 | 
			
		||||
    set(QT_VERSION 6.5.0)
 | 
			
		||||
    set(ECM_VERSION 5.240)
 | 
			
		||||
    set(KF_VERSION 5.240) # KDE Neon weirdness
 | 
			
		||||
    # API that was deprecated before Qt 5.15 causes a compile error
 | 
			
		||||
    add_compile_definitions(QT_DISABLE_DEPRECATED_BEFORE=0x060400)
 | 
			
		||||
    # Something to add to filenames for this specific Qt version
 | 
			
		||||
    set(QT_VERSION_SUFFIX "-qt6")
 | 
			
		||||
else()
 | 
			
		||||
    message(STATUS "Building Calamares with Qt5")
 | 
			
		||||
    set(qtname "Qt5")
 | 
			
		||||
    set(kfname "KF5")
 | 
			
		||||
    set(QT_VERSION 5.15.0)
 | 
			
		||||
    set(ECM_VERSION 5.78)
 | 
			
		||||
    set(KF_VERSION 5.78)
 | 
			
		||||
    # API that was deprecated before Qt 5.15 causes a compile error
 | 
			
		||||
    add_compile_definitions(QT_DISABLE_DEPRECATED_BEFORE=0x050f00)
 | 
			
		||||
    # Something to add to filenames for this specific Qt version
 | 
			
		||||
    set(QT_VERSION_SUFFIX "")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
set(BOOSTPYTHON_VERSION 1.72.0)
 | 
			
		||||
set(PYTHONLIBS_VERSION 3.6)
 | 
			
		||||
set(YAMLCPP_VERSION 0.5.1)
 | 
			
		||||
 | 
			
		||||
### CMAKE SETUP
 | 
			
		||||
#
 | 
			
		||||
set( CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CMakeModules" )
 | 
			
		||||
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CMakeModules")
 | 
			
		||||
 | 
			
		||||
# Enable IN_LIST
 | 
			
		||||
if( POLICY CMP0057 )
 | 
			
		||||
    cmake_policy( SET CMP0057 NEW )
 | 
			
		||||
if(POLICY CMP0057)
 | 
			
		||||
    cmake_policy(SET CMP0057 NEW)
 | 
			
		||||
endif()
 | 
			
		||||
# Let ``AUTOMOC`` and ``AUTOUIC`` process ``GENERATED`` files.
 | 
			
		||||
if( POLICY CMP0071 )
 | 
			
		||||
    cmake_policy( SET CMP0071 NEW )
 | 
			
		||||
if(POLICY CMP0071)
 | 
			
		||||
    cmake_policy(SET CMP0071 NEW)
 | 
			
		||||
endif()
 | 
			
		||||
# Recognize more macros to trigger automoc
 | 
			
		||||
if(NOT CMAKE_VERSION VERSION_LESS "3.10.0")
 | 
			
		||||
    list(APPEND CMAKE_AUTOMOC_MACRO_NAMES
 | 
			
		||||
    list(
 | 
			
		||||
        APPEND
 | 
			
		||||
        CMAKE_AUTOMOC_MACRO_NAMES
 | 
			
		||||
        "K_PLUGIN_FACTORY_WITH_JSON"
 | 
			
		||||
        "K_EXPORT_PLASMA_DATAENGINE_WITH_JSON"
 | 
			
		||||
        "K_EXPORT_PLASMA_RUNNER"
 | 
			
		||||
@@ -175,40 +220,50 @@ if(NOT CMAKE_VERSION VERSION_LESS "3.10.0")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
# CMake Modules
 | 
			
		||||
include( CMakePackageConfigHelpers )
 | 
			
		||||
include( CTest )
 | 
			
		||||
include( FeatureSummary )
 | 
			
		||||
include(CMakePackageConfigHelpers)
 | 
			
		||||
include(CTest)
 | 
			
		||||
include(FeatureSummary)
 | 
			
		||||
 | 
			
		||||
# Calamares Modules
 | 
			
		||||
include( CMakeColors )
 | 
			
		||||
include(CMakeColors)
 | 
			
		||||
 | 
			
		||||
### C++ SETUP
 | 
			
		||||
#
 | 
			
		||||
set( CMAKE_CXX_STANDARD 17 )
 | 
			
		||||
set( CMAKE_CXX_STANDARD_REQUIRED ON )
 | 
			
		||||
set( CMAKE_CXX_FLAGS                "${CMAKE_CXX_FLAGS} -Wall -Werror=return-type" )
 | 
			
		||||
set( CMAKE_CXX_FLAGS_DEBUG          "-Og -g ${CMAKE_CXX_FLAGS_DEBUG}" )
 | 
			
		||||
set( CMAKE_CXX_FLAGS_MINSIZEREL     "-Os -DNDEBUG" )
 | 
			
		||||
set( CMAKE_CXX_FLAGS_RELEASE        "-O3 -DNDEBUG" )
 | 
			
		||||
set( CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g" )
 | 
			
		||||
set(CMAKE_CXX_STANDARD 17)
 | 
			
		||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
 | 
			
		||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror=return-type")
 | 
			
		||||
set(CMAKE_CXX_FLAGS_DEBUG "-Og -g ${CMAKE_CXX_FLAGS_DEBUG}")
 | 
			
		||||
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG")
 | 
			
		||||
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
 | 
			
		||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
 | 
			
		||||
 | 
			
		||||
set( CMAKE_C_STANDARD 99 )
 | 
			
		||||
set( CMAKE_C_STANDARD_REQUIRED ON )
 | 
			
		||||
set( CMAKE_C_FLAGS                  "${CMAKE_C_FLAGS} -Wall" )
 | 
			
		||||
set( CMAKE_C_FLAGS_DEBUG            "-Og -g" )
 | 
			
		||||
set( CMAKE_C_FLAGS_MINSIZEREL       "-Os -DNDEBUG" )
 | 
			
		||||
set( CMAKE_C_FLAGS_RELEASE          "-O4 -DNDEBUG" )
 | 
			
		||||
set( CMAKE_C_FLAGS_RELWITHDEBINFO   "-O2 -g" )
 | 
			
		||||
set(CMAKE_C_STANDARD 99)
 | 
			
		||||
set(CMAKE_C_STANDARD_REQUIRED ON)
 | 
			
		||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
 | 
			
		||||
set(CMAKE_C_FLAGS_DEBUG "-Og -g")
 | 
			
		||||
set(CMAKE_C_FLAGS_MINSIZEREL "-Os -DNDEBUG")
 | 
			
		||||
set(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG")
 | 
			
		||||
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -g")
 | 
			
		||||
 | 
			
		||||
set( CMAKE_SHARED_LINKER_FLAGS      "-Wl,--no-undefined -Wl,--fatal-warnings" )
 | 
			
		||||
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--no-undefined -Wl,--fatal-warnings ${CMAKE_SHARED_LINKER_FLAGS}")
 | 
			
		||||
 | 
			
		||||
if( CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
 | 
			
		||||
    message( STATUS "Found Clang ${CMAKE_CXX_COMPILER_VERSION}, setting up Clang-specific compiler flags." )
 | 
			
		||||
# If no build type is set, pick a reasonable one
 | 
			
		||||
if(NOT CMAKE_BUILD_TYPE)
 | 
			
		||||
    if(CALAMARES_RELEASE_MODE)
 | 
			
		||||
        set(CMAKE_BUILD_TYPE "RelWithDebInfo")
 | 
			
		||||
    else()
 | 
			
		||||
        set(CMAKE_BUILD_TYPE "Debug")
 | 
			
		||||
    endif()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
 | 
			
		||||
    message(STATUS "Found Clang ${CMAKE_CXX_COMPILER_VERSION}, setting up Clang-specific compiler flags.")
 | 
			
		||||
 | 
			
		||||
    # Clang warnings: doing *everything* is counter-productive, since it warns
 | 
			
		||||
    # about things which we can't fix (e.g. C++98 incompatibilities, but
 | 
			
		||||
    # Calamares is C++17).
 | 
			
		||||
    foreach( CLANG_WARNINGS
 | 
			
		||||
    foreach(
 | 
			
		||||
        CLANG_WARNINGS
 | 
			
		||||
        -Weverything
 | 
			
		||||
        -Wno-c++98-compat
 | 
			
		||||
        -Wno-c++98-compat-pedantic
 | 
			
		||||
@@ -220,229 +275,247 @@ if( CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
 | 
			
		||||
        -Wno-documentation-unknown-command
 | 
			
		||||
        -Wno-unknown-warning-option
 | 
			
		||||
    )
 | 
			
		||||
        string( APPEND CMAKE_CXX_FLAGS " ${CLANG_WARNINGS}" )
 | 
			
		||||
        string(APPEND CMAKE_CXX_FLAGS " ${CLANG_WARNINGS}")
 | 
			
		||||
    endforeach()
 | 
			
		||||
 | 
			
		||||
    # The dwarf-debugging flags are slightly different, too
 | 
			
		||||
    string( APPEND CMAKE_CXX_FLAGS_DEBUG " -gdwarf" )
 | 
			
		||||
    string( APPEND CMAKE_C_FLAGS_DEBUG " -gdwarf" )
 | 
			
		||||
    string(APPEND CMAKE_CXX_FLAGS_DEBUG " -gdwarf")
 | 
			
		||||
    string(APPEND CMAKE_C_FLAGS_DEBUG " -gdwarf")
 | 
			
		||||
 | 
			
		||||
    # Third-party code where we don't care so much about compiler warnings
 | 
			
		||||
    # (because it's uncomfortable to patch) get different flags; use
 | 
			
		||||
    #       mark_thirdparty_code( <file> [<file>...] )
 | 
			
		||||
    # to switch off warnings for those sources.
 | 
			
		||||
    set( SUPPRESS_3RDPARTY_WARNINGS "-Wno-everything" )
 | 
			
		||||
    set(SUPPRESS_3RDPARTY_WARNINGS "-Wno-everything")
 | 
			
		||||
 | 
			
		||||
    set( CMAKE_TOOLCHAIN_PREFIX "llvm-" )
 | 
			
		||||
    set(CMAKE_TOOLCHAIN_PREFIX "llvm-")
 | 
			
		||||
 | 
			
		||||
    # The path prefix is only relevant for CMake 3.16 and later, fixes #1286
 | 
			
		||||
    set( CMAKE_AUTOMOC_PATH_PREFIX OFF )
 | 
			
		||||
    set( CALAMARES_AUTOMOC_OPTIONS "-butils/moc-warnings.h" )
 | 
			
		||||
    set( CALAMARES_AUTOUIC_OPTIONS --include utils/moc-warnings.h )
 | 
			
		||||
    set(CMAKE_AUTOMOC_PATH_PREFIX OFF)
 | 
			
		||||
    set(CALAMARES_AUTOMOC_OPTIONS "-butils/moc-warnings.h")
 | 
			
		||||
    set(CALAMARES_AUTOUIC_OPTIONS --include utils/moc-warnings.h)
 | 
			
		||||
else()
 | 
			
		||||
    set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wnon-virtual-dtor -Woverloaded-virtual" )
 | 
			
		||||
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wnon-virtual-dtor -Woverloaded-virtual")
 | 
			
		||||
 | 
			
		||||
    set( SUPPRESS_3RDPARTY_WARNINGS "" )
 | 
			
		||||
    set(SUPPRESS_3RDPARTY_WARNINGS "")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
# Use mark_thirdparty_code() to reduce warnings from the compiler
 | 
			
		||||
# on code that we're not going to fix. Call this with a list of files.
 | 
			
		||||
macro(mark_thirdparty_code)
 | 
			
		||||
    set_source_files_properties( ${ARGV}
 | 
			
		||||
        PROPERTIES
 | 
			
		||||
            COMPILE_FLAGS "${SUPPRESS_3RDPARTY_WARNINGS}"
 | 
			
		||||
            COMPILE_DEFINITIONS "THIRDPARTY"
 | 
			
		||||
    set_source_files_properties(
 | 
			
		||||
        ${ARGV}
 | 
			
		||||
        PROPERTIES COMPILE_FLAGS "${SUPPRESS_3RDPARTY_WARNINGS}" COMPILE_DEFINITIONS "THIRDPARTY"
 | 
			
		||||
    )
 | 
			
		||||
endmacro()
 | 
			
		||||
 | 
			
		||||
if( CMAKE_COMPILER_IS_GNUCXX )
 | 
			
		||||
    if( CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.9 OR
 | 
			
		||||
        CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 4.9 )
 | 
			
		||||
        message( STATUS "Found GNU g++ ${CMAKE_CXX_COMPILER_VERSION}, enabling colorized error messages." )
 | 
			
		||||
        set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=auto" )
 | 
			
		||||
if(CMAKE_COMPILER_IS_GNUCXX)
 | 
			
		||||
    if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.9 OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 4.9)
 | 
			
		||||
        message(STATUS "Found GNU g++ ${CMAKE_CXX_COMPILER_VERSION}, enabling colorized error messages.")
 | 
			
		||||
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=auto")
 | 
			
		||||
    endif()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### DEPENDENCIES
 | 
			
		||||
#
 | 
			
		||||
find_package( Qt5 ${QT_VERSION} CONFIG REQUIRED Concurrent Core Gui LinguistTools Network Svg Widgets )
 | 
			
		||||
if( WITH_QML )
 | 
			
		||||
    find_package( Qt5 ${QT_VERSION} CONFIG REQUIRED Quick QuickWidgets )
 | 
			
		||||
find_package(${qtname} ${QT_VERSION} CONFIG REQUIRED Concurrent Core DBus Gui LinguistTools Network Svg Widgets)
 | 
			
		||||
if(WITH_QML)
 | 
			
		||||
    find_package(${qtname} ${QT_VERSION} CONFIG REQUIRED Quick QuickWidgets)
 | 
			
		||||
endif()
 | 
			
		||||
# Optional Qt parts
 | 
			
		||||
find_package( Qt5DBus CONFIG )
 | 
			
		||||
# Note that some modules need more Qt modules, optionally.
 | 
			
		||||
 | 
			
		||||
find_package( YAMLCPP ${YAMLCPP_VERSION} REQUIRED )
 | 
			
		||||
if( INSTALL_POLKIT )
 | 
			
		||||
    find_package( PolkitQt5-1 REQUIRED )
 | 
			
		||||
else()
 | 
			
		||||
    # Find it anyway, for dependencies-reporting
 | 
			
		||||
    find_package( PolkitQt5-1 )
 | 
			
		||||
find_package(YAMLCPP ${YAMLCPP_VERSION})
 | 
			
		||||
set_package_properties(
 | 
			
		||||
    YAMLCPP
 | 
			
		||||
    PROPERTIES
 | 
			
		||||
    TYPE REQUIRED
 | 
			
		||||
    DESCRIPTION "YAML parser for C++"
 | 
			
		||||
    PURPOSE "Parsing of configuration files"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
find_package(Polkit${qtname}-1)
 | 
			
		||||
if(INSTALL_POLKIT)
 | 
			
		||||
    set_package_properties(
 | 
			
		||||
        Polkit${qtname}-1
 | 
			
		||||
        PROPERTIES
 | 
			
		||||
        TYPE REQUIRED
 | 
			
		||||
    )
 | 
			
		||||
endif()
 | 
			
		||||
set_package_properties(
 | 
			
		||||
    PolkitQt5-1 PROPERTIES
 | 
			
		||||
    DESCRIPTION "Qt5 support for Polkit"
 | 
			
		||||
    Polkit${qtname}-1
 | 
			
		||||
    PROPERTIES
 | 
			
		||||
    DESCRIPTION "${qtname} support for Polkit"
 | 
			
		||||
    URL "https://cgit.kde.org/polkit-qt-1.git"
 | 
			
		||||
    PURPOSE "PolkitQt5-1 helps with installing Polkit configuration"
 | 
			
		||||
    PURPOSE "Polkit${qtname}-1 helps with installing Polkit configuration"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
# Find ECM once, and add it to the module search path; Calamares
 | 
			
		||||
# modules that need ECM can do
 | 
			
		||||
#   find_package(ECM ${ECM_VERSION} REQUIRED NO_MODULE),
 | 
			
		||||
#   if(ECM_FOUND)
 | 
			
		||||
# no need to mess with the module path after.
 | 
			
		||||
find_package(ECM ${ECM_VERSION} NO_MODULE)
 | 
			
		||||
if( ECM_FOUND )
 | 
			
		||||
if(ECM_FOUND)
 | 
			
		||||
    message(STATUS "Found KDE ECM ${ECM_MODULE_PATH}")
 | 
			
		||||
    set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${CMAKE_MODULE_PATH})
 | 
			
		||||
    if ( BUILD_TESTING )
 | 
			
		||||
    if(BUILD_TESTING)
 | 
			
		||||
        # ECM implies that we can build the tests, too
 | 
			
		||||
        find_package( Qt5 COMPONENTS Test REQUIRED )
 | 
			
		||||
        include( ECMAddTests )
 | 
			
		||||
        find_package(${qtname} COMPONENTS Test REQUIRED)
 | 
			
		||||
        include(ECMAddTests)
 | 
			
		||||
    endif()
 | 
			
		||||
    include(KDEInstallDirs)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
find_package( KF5 QUIET COMPONENTS CoreAddons Crash DBusAddons )
 | 
			
		||||
find_package(${kfname}CoreAddons ${KF_VERSION} QUIET)
 | 
			
		||||
set_package_properties(
 | 
			
		||||
    KF5::CoreAddons PROPERTIES
 | 
			
		||||
    ${kfname}CoreAddons
 | 
			
		||||
    PROPERTIES
 | 
			
		||||
    TYPE REQUIRED
 | 
			
		||||
    DESCRIPTION "Classes built on QtCore for About Data"
 | 
			
		||||
    URL "https://api.kde.org/frameworks/kcoreaddons/"
 | 
			
		||||
    PURPOSE "About Calamares"
 | 
			
		||||
    DESCRIPTION "KDE Framework CoreAddons"
 | 
			
		||||
    URL "https://api.kde.org/frameworks/"
 | 
			
		||||
    PURPOSE "Essential Framework for AboutData and Macros"
 | 
			
		||||
)
 | 
			
		||||
if( NOT KF5Crash_FOUND )
 | 
			
		||||
    if( WITH_KF5Crash )
 | 
			
		||||
        message(WARNING "WITH_KF5Crash is set, but KF5::Crash is not available.")
 | 
			
		||||
    endif()
 | 
			
		||||
    set( WITH_KF5Crash OFF )
 | 
			
		||||
endif()
 | 
			
		||||
if( NOT KF5DBusAddons_FOUND )
 | 
			
		||||
    if( WITH_KF5DBus )
 | 
			
		||||
        message(WARNING "WITH_KF5DBus is set, but KF5::DBusAddons is not available.")
 | 
			
		||||
    endif()
 | 
			
		||||
    set( WITH_KF5DBus OFF )
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
# TODO:3.3: Use FindPython3 instead
 | 
			
		||||
find_package( PythonInterp ${PYTHONLIBS_VERSION} )
 | 
			
		||||
# After this point, there should be no REQUIRED find_packages,
 | 
			
		||||
# since we want tidy reporting of optional dependencies.
 | 
			
		||||
feature_summary(
 | 
			
		||||
    WHAT REQUIRED_PACKAGES_NOT_FOUND
 | 
			
		||||
    FATAL_ON_MISSING_REQUIRED_PACKAGES
 | 
			
		||||
    DESCRIPTION "The following REQUIRED packages were not found:"
 | 
			
		||||
    QUIET_ON_EMPTY
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# OPTIONAL DEPENDENCIES
 | 
			
		||||
#
 | 
			
		||||
# First, set KF back to optional so that any missing components don't trip us up.
 | 
			
		||||
find_package(${kfname}Crash ${KF_VERSION} QUIET)
 | 
			
		||||
set_package_properties(
 | 
			
		||||
    PythonInterp PROPERTIES
 | 
			
		||||
    DESCRIPTION "Python 3 interpreter."
 | 
			
		||||
    URL "https://python.org"
 | 
			
		||||
    PURPOSE "Python 3 interpreter for certain tests."
 | 
			
		||||
    ${kfname}Crash
 | 
			
		||||
    PROPERTIES
 | 
			
		||||
    TYPE OPTIONAL
 | 
			
		||||
    DESCRIPTION "KDE Framework Crash"
 | 
			
		||||
    URL "https://api.kde.org/frameworks/"
 | 
			
		||||
    PURPOSE "Framework for sending Crash Dumps"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
set( _schema_explanation "" )
 | 
			
		||||
if ( PYTHONINTERP_FOUND )
 | 
			
		||||
    if ( BUILD_SCHEMA_TESTING )
 | 
			
		||||
if(NOT TARGET ${kfname}::Crash)
 | 
			
		||||
    if(BUILD_CRASH_REPORTING)
 | 
			
		||||
        message(WARNING "BUILD_CRASH_REPORTING is set, but ${kfname}::Crash is not available.")
 | 
			
		||||
    endif()
 | 
			
		||||
    set(BUILD_CRASH_REPORTING OFF)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
find_package(Python ${PYTHONLIBS_VERSION} COMPONENTS Interpreter Development)
 | 
			
		||||
set_package_properties(
 | 
			
		||||
    Python
 | 
			
		||||
    PROPERTIES
 | 
			
		||||
    DESCRIPTION "Python3 interpreter."
 | 
			
		||||
    URL "https://python.org"
 | 
			
		||||
    PURPOSE "Python3 interpreter for certain tests."
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
set(_schema_explanation "")
 | 
			
		||||
if(Python_Interpreter_FOUND)
 | 
			
		||||
    if(BUILD_SCHEMA_TESTING)
 | 
			
		||||
        # The configuration validator script has some dependencies,
 | 
			
		||||
        # and if they are not installed, don't run. If errors out
 | 
			
		||||
        # with exit(1) on missing dependencies.
 | 
			
		||||
        if ( CALAMARES_CONFIGVALIDATOR_CHECKED )
 | 
			
		||||
            set( _validator_deps ${CALAMARES_CONFIGVALIDATOR_RESULT} )
 | 
			
		||||
        if(CALAMARES_CONFIGVALIDATOR_CHECKED)
 | 
			
		||||
            message(STATUS "Using cached config-validation result")
 | 
			
		||||
            set(_validator_deps ${CALAMARES_CONFIGVALIDATOR_RESULT})
 | 
			
		||||
        else()
 | 
			
		||||
            exec_program( ${PYTHON_EXECUTABLE} ARGS "${CMAKE_SOURCE_DIR}/ci/configvalidator.py" -x RETURN_VALUE _validator_deps )
 | 
			
		||||
            set( CALAMARES_CONFIGVALIDATOR_CHECKED TRUE CACHE INTERNAL "Dependencies for configvalidator checked" )
 | 
			
		||||
            set( CALAMARES_CONFIGVALIDATOR_RESULT ${_validator_deps} CACHE INTERNAL "Result of configvalidator dependency check" )
 | 
			
		||||
            execute_process(
 | 
			
		||||
                COMMAND ${Python_EXECUTABLE} "${CMAKE_SOURCE_DIR}/ci/configvalidator.py" -x
 | 
			
		||||
                RESULT_VARIABLE _validator_deps
 | 
			
		||||
            )
 | 
			
		||||
            set(CALAMARES_CONFIGVALIDATOR_CHECKED TRUE CACHE INTERNAL "Dependencies for configvalidator checked")
 | 
			
		||||
            set(CALAMARES_CONFIGVALIDATOR_RESULT ${_validator_deps}
 | 
			
		||||
                CACHE INTERNAL "Result of configvalidator dependency check"
 | 
			
		||||
            )
 | 
			
		||||
        endif()
 | 
			
		||||
        # It should never succeed, but only returns 1 when the imports fail
 | 
			
		||||
        if ( _validator_deps EQUAL 1 )
 | 
			
		||||
            set( _schema_explanation " Missing dependencies for configvalidator.py." )
 | 
			
		||||
            set( BUILD_SCHEMA_TESTING OFF )
 | 
			
		||||
        if(_validator_deps EQUAL 1)
 | 
			
		||||
            message(STATUS "Checked for config-validation dependencies: NOT-FOUND")
 | 
			
		||||
            set(_schema_explanation " Missing dependencies for configvalidator.py.")
 | 
			
		||||
            set(BUILD_SCHEMA_TESTING OFF)
 | 
			
		||||
        else()
 | 
			
		||||
            message(STATUS "Checked for config-validation dependencies: found")
 | 
			
		||||
        endif()
 | 
			
		||||
    else()
 | 
			
		||||
        set(CALAMARES_CONFIGVALIDATOR_CHECKED OFF CACHE INTERNAL "Dependencies for configvalidator checked")
 | 
			
		||||
    endif()
 | 
			
		||||
else()
 | 
			
		||||
    # Can't run schema tests without Python3.
 | 
			
		||||
    set( _schema_explanation " Missing Python3." )
 | 
			
		||||
    set( BUILD_SCHEMA_TESTING OFF )
 | 
			
		||||
    set(_schema_explanation " Missing Python3.")
 | 
			
		||||
    set(BUILD_SCHEMA_TESTING OFF)
 | 
			
		||||
    set(CALAMARES_CONFIGVALIDATOR_CHECKED OFF CACHE INTERNAL "Dependencies for configvalidator checked")
 | 
			
		||||
endif()
 | 
			
		||||
add_feature_info( yaml-schema BUILD_SCHEMA_TESTING "Validate YAML (config files) with schema.${_schema_explanation}" )
 | 
			
		||||
add_feature_info(yaml-schema BUILD_SCHEMA_TESTING "Validate YAML (config files) with schema.${_schema_explanation}")
 | 
			
		||||
 | 
			
		||||
find_package( PythonLibs ${PYTHONLIBS_VERSION} )
 | 
			
		||||
set_package_properties(
 | 
			
		||||
    PythonLibs PROPERTIES
 | 
			
		||||
    DESCRIPTION "C interface libraries for the Python 3 interpreter."
 | 
			
		||||
    URL "https://python.org"
 | 
			
		||||
    PURPOSE "Python 3 is used for Python job modules."
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
if ( PYTHONLIBS_FOUND )
 | 
			
		||||
    # TODO:3.3: Require Boost + CMake; sort out Boost::Python
 | 
			
		||||
    # Since Boost provides CMake config files (starting with Boost 1.70.
 | 
			
		||||
    # or so) the mess that is the Calamares find code picks the wrong
 | 
			
		||||
    # bits. Suppress those CMake config files, as suggested by @jmrcpn
 | 
			
		||||
    set(Boost_NO_BOOST_CMAKE ON)
 | 
			
		||||
    include( BoostPython3 )
 | 
			
		||||
    find_boost_python3( ${BOOSTPYTHON_VERSION} ${PYTHONLIBS_VERSION_STRING} CALAMARES_BOOST_PYTHON3_FOUND )
 | 
			
		||||
    set_package_properties(
 | 
			
		||||
        Boost PROPERTIES
 | 
			
		||||
        PURPOSE "Boost.Python is used for Python job modules."
 | 
			
		||||
    )
 | 
			
		||||
    # TODO:3.3: Remove PythonQt support
 | 
			
		||||
    find_package( PythonQt )
 | 
			
		||||
    set_package_properties( PythonQt PROPERTIES
 | 
			
		||||
        DESCRIPTION "A Python embedding solution for Qt applications."
 | 
			
		||||
        URL "http://pythonqt.sourceforge.net"
 | 
			
		||||
        PURPOSE "PythonQt is used for Python view modules."
 | 
			
		||||
    )
 | 
			
		||||
if(NOT Python_Development_FOUND)
 | 
			
		||||
    message(STATUS "Disabling Python modules")
 | 
			
		||||
    set(WITH_PYTHON OFF)
 | 
			
		||||
    set(WITH_PYBIND11 OFF)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if( NOT PYTHONLIBS_FOUND OR NOT CALAMARES_BOOST_PYTHON3_FOUND )
 | 
			
		||||
    message(STATUS "Disabling Boost::Python modules")
 | 
			
		||||
    set( WITH_PYTHON OFF )
 | 
			
		||||
endif()
 | 
			
		||||
if( NOT PYTHONLIBS_FOUND OR NOT PYTHONQT_FOUND )
 | 
			
		||||
    message(STATUS "Disabling PythonQt modules")
 | 
			
		||||
    set( WITH_PYTHONQT OFF )
 | 
			
		||||
if(WITH_PYTHON AND NOT WITH_PYBIND11)
 | 
			
		||||
    find_package(boost_python)
 | 
			
		||||
    if(NOT TARGET Boost::python)
 | 
			
		||||
        find_package(Boost ${BOOSTPYTHON_VERSION} COMPONENTS python)
 | 
			
		||||
        set_package_properties(Boost PROPERTIES
 | 
			
		||||
            PURPOSE "Boost.Python is used for Python job modules (because WITH_PYBIND11 is OFF)."
 | 
			
		||||
            TYPE REQUIRED
 | 
			
		||||
        )
 | 
			
		||||
    else()
 | 
			
		||||
        message(STATUS "Found boost_python with target Boost::python")
 | 
			
		||||
        set(Boost_FOUND ON)
 | 
			
		||||
    endif()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
# Now we know the state of the ABI-options, copy them into "Calamares_"
 | 
			
		||||
# prefixed variables, to match how the variables would-be-named
 | 
			
		||||
# when building out-of-tree.
 | 
			
		||||
set(Calamares_WITH_PYBIND11 ${WITH_PYBIND11})
 | 
			
		||||
set(Calamares_WITH_PYTHON ${WITH_PYTHON})
 | 
			
		||||
set(Calamares_WITH_PYTHONQT ${WITH_PYTHONQT})
 | 
			
		||||
set(Calamares_WITH_QML ${WITH_QML})
 | 
			
		||||
set(Calamares_WITH_QT6 ${WITH_QT6})
 | 
			
		||||
 | 
			
		||||
### Transifex Translation status
 | 
			
		||||
#
 | 
			
		||||
# Construct language lists for use. This massages the language lists
 | 
			
		||||
# for use with older Qt (which does not support Esperanto) and checks
 | 
			
		||||
# for some obvious error. The actual work of compiling translations
 | 
			
		||||
# is done in the lang/ directory.
 | 
			
		||||
# Construct language lists for use. This massages the language lists if
 | 
			
		||||
# needed and checks for some obvious errors. The actual work of
 | 
			
		||||
# compiling translations is done in the lang/ directory.
 | 
			
		||||
#
 | 
			
		||||
if( Qt5_VERSION VERSION_GREATER 5.12.1 )
 | 
			
		||||
    # At least Qt 5.12.2 seems to support Esperanto in QLocale
 | 
			
		||||
    if( "eo" IN_LIST _tx_incomplete )
 | 
			
		||||
        message(STATUS "Esperanto support since Qt 5.12.2, enabling Esperanto locale")
 | 
			
		||||
        list( REMOVE_ITEM _tx_incomplete "eo" )
 | 
			
		||||
        list( APPEND _tx_ok "eo" )
 | 
			
		||||
    endif()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
set( curr_tx ${_tx_complete} ${_tx_good} ${_tx_ok} ${_tx_incomplete} )
 | 
			
		||||
set( tx_errors OFF )
 | 
			
		||||
if ( curr_tx )
 | 
			
		||||
set(curr_tx ${_tx_complete} ${_tx_good} ${_tx_ok} ${_tx_incomplete})
 | 
			
		||||
set(tx_errors OFF)
 | 
			
		||||
if(curr_tx)
 | 
			
		||||
    # New in list
 | 
			
		||||
    foreach( l ${curr_tx} )
 | 
			
		||||
        set( p_l "lang/calamares_${l}.ts" )
 | 
			
		||||
        if( NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${p_l} )
 | 
			
		||||
    foreach(l ${curr_tx})
 | 
			
		||||
        set(p_l "lang/calamares_${l}.ts")
 | 
			
		||||
        if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${p_l})
 | 
			
		||||
            message(WARNING "Language ${l} has no .ts file yet.")
 | 
			
		||||
            set( tx_errors ON )
 | 
			
		||||
            set(tx_errors ON)
 | 
			
		||||
        endif()
 | 
			
		||||
    endforeach()
 | 
			
		||||
 | 
			
		||||
    unset( p_l )
 | 
			
		||||
    unset( l )
 | 
			
		||||
    unset(p_l)
 | 
			
		||||
    unset(l)
 | 
			
		||||
endif()
 | 
			
		||||
unset( curr_tx )
 | 
			
		||||
if( tx_errors )
 | 
			
		||||
    message( FATAL_ERROR "Translation warnings, see above." )
 | 
			
		||||
unset(curr_tx)
 | 
			
		||||
if(tx_errors)
 | 
			
		||||
    message(FATAL_ERROR "Translation warnings, see above.")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
set( CALAMARES_TRANSLATION_LANGUAGES en ${_tx_complete} ${_tx_good} ${_tx_ok} )
 | 
			
		||||
list( SORT CALAMARES_TRANSLATION_LANGUAGES )
 | 
			
		||||
set(CALAMARES_TRANSLATION_LANGUAGES en ${_tx_complete} ${_tx_good} ${_tx_ok})
 | 
			
		||||
if(NOT CALAMARES_RELEASE_MODE)
 | 
			
		||||
    # Outside of release mode, enable all the languages
 | 
			
		||||
    list(APPEND CALAMARES_TRANSLATION_LANGUAGES ${_tx_incomplete})
 | 
			
		||||
endif()
 | 
			
		||||
list(SORT CALAMARES_TRANSLATION_LANGUAGES)
 | 
			
		||||
list(REMOVE_DUPLICATES CALAMARES_TRANSLATION_LANGUAGES)
 | 
			
		||||
 | 
			
		||||
add_subdirectory( lang )  # i18n tools
 | 
			
		||||
add_subdirectory(lang) # i18n tools
 | 
			
		||||
 | 
			
		||||
### Example Distro
 | 
			
		||||
#
 | 
			
		||||
@@ -461,22 +534,22 @@ add_subdirectory( lang )  # i18n tools
 | 
			
		||||
#
 | 
			
		||||
#   make example-distro
 | 
			
		||||
#
 | 
			
		||||
find_program( mksquashfs_PROGRAM mksquashfs )
 | 
			
		||||
if( mksquashfs_PROGRAM )
 | 
			
		||||
    set( mksquashfs_FOUND ON )
 | 
			
		||||
    set( src_fs ${CMAKE_SOURCE_DIR}/data/example-root/ )
 | 
			
		||||
    set( dst_fs ${CMAKE_BINARY_DIR}/example.sqfs )
 | 
			
		||||
    if( EXISTS ${src_fs} )
 | 
			
		||||
find_program(mksquashfs_PROGRAM mksquashfs)
 | 
			
		||||
if(mksquashfs_PROGRAM)
 | 
			
		||||
    set(mksquashfs_FOUND ON)
 | 
			
		||||
    set(src_fs ${CMAKE_SOURCE_DIR}/data/example-root/)
 | 
			
		||||
    set(dst_fs ${CMAKE_BINARY_DIR}/example.sqfs)
 | 
			
		||||
    if(EXISTS ${src_fs})
 | 
			
		||||
        # based on the build host. If /lib64 exists, assume it is needed.
 | 
			
		||||
        # Collect directories needed for a minimal binary distro,
 | 
			
		||||
        # Note that the last path component is added to the root, so
 | 
			
		||||
        # if you add /usr/sbin here, it will be put into /sbin_1.
 | 
			
		||||
        # Add such paths to /etc/profile under ${src_fs}.
 | 
			
		||||
        set( candidate_fs /sbin /bin /lib /lib64 )
 | 
			
		||||
        set( host_fs "" )
 | 
			
		||||
        foreach( c_fs ${candidate_fs} )
 | 
			
		||||
            if( EXISTS ${c_fs} )
 | 
			
		||||
                list( APPEND host_fs ${c_fs} )
 | 
			
		||||
        set(candidate_fs /sbin /bin /lib /lib64)
 | 
			
		||||
        set(host_fs "")
 | 
			
		||||
        foreach(c_fs ${candidate_fs})
 | 
			
		||||
            if(EXISTS ${c_fs})
 | 
			
		||||
                list(APPEND host_fs ${c_fs})
 | 
			
		||||
            endif()
 | 
			
		||||
        endforeach()
 | 
			
		||||
        add_custom_command(
 | 
			
		||||
@@ -487,105 +560,92 @@ if( mksquashfs_PROGRAM )
 | 
			
		||||
        add_custom_target(example-distro DEPENDS ${dst_fs})
 | 
			
		||||
    endif()
 | 
			
		||||
else()
 | 
			
		||||
    set( mksquashfs_FOUND OFF )
 | 
			
		||||
    set(mksquashfs_FOUND OFF)
 | 
			
		||||
endif()
 | 
			
		||||
# Doesn't list mksquashfs as an optional dep, though, because it
 | 
			
		||||
# hasn't been sent through the find_package() scheme.
 | 
			
		||||
#
 | 
			
		||||
# "http://tldp.org/HOWTO/SquashFS-HOWTO/creatingandusing.html"
 | 
			
		||||
add_feature_info( ExampleDistro ${mksquashfs_FOUND} "Create example-distro target.")
 | 
			
		||||
 | 
			
		||||
add_feature_info(ExampleDistro ${mksquashfs_FOUND} "Create example-distro target.")
 | 
			
		||||
 | 
			
		||||
### CALAMARES PROPER
 | 
			
		||||
#
 | 
			
		||||
set( CALAMARES_VERSION ${CALAMARES_VERSION_MAJOR}.${CALAMARES_VERSION_MINOR}.${CALAMARES_VERSION_PATCH} )
 | 
			
		||||
# In rare cases we have hotfix-releases with a tweak
 | 
			
		||||
if( CALAMARES_VERSION_TWEAK )
 | 
			
		||||
    set( CALAMARES_VERSION "${CALAMARES_VERSION}.${CALAMARES_VERSION_TWEAK}" )
 | 
			
		||||
endif()
 | 
			
		||||
set( CALAMARES_VERSION_SHORT "${CALAMARES_VERSION}" )
 | 
			
		||||
 | 
			
		||||
# Additional info for non-release builds. The "extended" version information
 | 
			
		||||
# with date and git information (commit, dirty status) is used only
 | 
			
		||||
# by CalamaresVersionX.h, which is included by consumers that need a full
 | 
			
		||||
# version number with all that information; normal consumers can include
 | 
			
		||||
# CalamaresVersion.h with more stable numbers.
 | 
			
		||||
if( NOT BUILD_RELEASE AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git/" )
 | 
			
		||||
    include( ExtendedVersion )
 | 
			
		||||
    extend_version( "${CALAMARES_VERSION}" OFF CALAMARES_VERSION_SHORT CALAMARES_VERSION )
 | 
			
		||||
if(NOT CALAMARES_RELEASE_MODE AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git/")
 | 
			
		||||
    include(ExtendedVersion)
 | 
			
		||||
    extend_version( "${CALAMARES_VERSION}" OFF CALAMARES_VERSION_SHORT CALAMARES_VERSION_LONG )
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
# Special target for not-RC (e.g. might-be-release) builds.
 | 
			
		||||
# This is used by the release script to get the version.
 | 
			
		||||
if ( CALAMARES_VERSION_RC EQUAL 0 )
 | 
			
		||||
    add_custom_target(show-version
 | 
			
		||||
        ${CMAKE_COMMAND} -E echo CALAMARES_VERSION=${CALAMARES_VERSION_SHORT}
 | 
			
		||||
        USES_TERMINAL
 | 
			
		||||
    )
 | 
			
		||||
# Special define for RC (e.g. not-a-release) builds.
 | 
			
		||||
# This is consumed via the CalamaresConfig.h header.
 | 
			
		||||
if(NOT CALAMARES_RELEASE_MODE)
 | 
			
		||||
    set(CALAMARES_VERSION_RC 1)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
# enforce using constBegin, constEnd for const-iterators
 | 
			
		||||
add_definitions(
 | 
			
		||||
    -DQT_STRICT_ITERATORS
 | 
			
		||||
    -DQT_SHARED
 | 
			
		||||
    -DQT_SHAREDPOINTER_TRACK_POINTERS
 | 
			
		||||
)
 | 
			
		||||
add_definitions(-DQT_STRICT_ITERATORS -DQT_SHARED -DQT_SHAREDPOINTER_TRACK_POINTERS)
 | 
			
		||||
 | 
			
		||||
# set paths
 | 
			
		||||
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" )
 | 
			
		||||
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" )
 | 
			
		||||
set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" )
 | 
			
		||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
 | 
			
		||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
 | 
			
		||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
 | 
			
		||||
 | 
			
		||||
# Better default installation paths: GNUInstallDirs defines
 | 
			
		||||
# CMAKE_INSTALL_FULL_SYSCONFDIR to be CMAKE_INSTALL_PREFIX/etc by default
 | 
			
		||||
# but we really want /etc
 | 
			
		||||
if( NOT DEFINED CMAKE_INSTALL_SYSCONFDIR )
 | 
			
		||||
    set( CMAKE_INSTALL_SYSCONFDIR "/etc" )
 | 
			
		||||
if(NOT DEFINED CMAKE_INSTALL_SYSCONFDIR)
 | 
			
		||||
    set(CMAKE_INSTALL_SYSCONFDIR "/etc")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
# make predefined install dirs available everywhere
 | 
			
		||||
include( GNUInstallDirs )
 | 
			
		||||
include(GNUInstallDirs)
 | 
			
		||||
 | 
			
		||||
# This is used by CalamaresAddLibrary; once Calamares is installed,
 | 
			
		||||
# the CalamaresConfig.cmake module sets this variable to the IMPORTED
 | 
			
		||||
# libraries for Calamares.
 | 
			
		||||
set( Calamares_LIBRARIES calamares )
 | 
			
		||||
set(Calamares_LIBRARIES calamares)
 | 
			
		||||
 | 
			
		||||
add_subdirectory( src )
 | 
			
		||||
add_subdirectory(3rdparty/kdsingleapplication)
 | 
			
		||||
if(WITH_PYBIND11)
 | 
			
		||||
    add_subdirectory(3rdparty/pybind11)
 | 
			
		||||
endif()
 | 
			
		||||
add_subdirectory(src)
 | 
			
		||||
 | 
			
		||||
add_feature_info(Python ${WITH_PYTHON} "Python job modules")
 | 
			
		||||
add_feature_info(PythonQt ${WITH_PYTHONQT} "Python view modules")
 | 
			
		||||
add_feature_info(Config ${INSTALL_CONFIG} "Install Calamares configuration")
 | 
			
		||||
add_feature_info(KCrash ${WITH_KF5Crash} "Crash dumps via KCrash")
 | 
			
		||||
add_feature_info(KDBusAddons ${WITH_KF5DBus} "Unique-application via DBus")
 | 
			
		||||
add_feature_info(Pybind11 ${WITH_PYBIND11} "Python using bundled pybind11")
 | 
			
		||||
add_feature_info(Qml ${WITH_QML} "QML UI support")
 | 
			
		||||
add_feature_info(Polkit ${INSTALL_POLKIT} "Install Polkit files")
 | 
			
		||||
add_feature_info(KCrash ${BUILD_CRASH_REPORTING} "Crash dumps via KCrash")
 | 
			
		||||
 | 
			
		||||
### Post-source configuration
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
find_package(${kfname} ${KF_VERSION} QUIET COMPONENTS CoreAddons)
 | 
			
		||||
 | 
			
		||||
### CMake infrastructure installation
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
set( CMAKE_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/Calamares" CACHE PATH  "Installation directory for CMake files" )
 | 
			
		||||
set( CMAKE_INSTALL_FULL_CMAKEDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_CMAKEDIR}" )
 | 
			
		||||
set(CMAKE_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/Calamares" CACHE PATH "Installation directory for CMake files")
 | 
			
		||||
set(CMAKE_INSTALL_FULL_CMAKEDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_CMAKEDIR}")
 | 
			
		||||
 | 
			
		||||
export( PACKAGE Calamares )
 | 
			
		||||
export(PACKAGE Calamares)
 | 
			
		||||
configure_package_config_file(
 | 
			
		||||
    "CalamaresConfig.cmake.in"
 | 
			
		||||
    "${PROJECT_BINARY_DIR}/CalamaresConfig.cmake"
 | 
			
		||||
    INSTALL_DESTINATION "${CMAKE_INSTALL_CMAKEDIR}"
 | 
			
		||||
    PATH_VARS
 | 
			
		||||
        CMAKE_INSTALL_INCLUDEDIR
 | 
			
		||||
        CMAKE_INSTALL_LIBDIR
 | 
			
		||||
        CMAKE_INSTALL_DATADIR
 | 
			
		||||
    PATH_VARS CMAKE_INSTALL_INCLUDEDIR CMAKE_INSTALL_LIBDIR CMAKE_INSTALL_DATADIR
 | 
			
		||||
)
 | 
			
		||||
write_basic_package_version_file(
 | 
			
		||||
    ${PROJECT_BINARY_DIR}/CalamaresConfigVersion.cmake
 | 
			
		||||
    VERSION ${PROJECT_VERSION}
 | 
			
		||||
    COMPATIBILITY SameMajorVersion
 | 
			
		||||
)
 | 
			
		||||
install(
 | 
			
		||||
    EXPORT Calamares
 | 
			
		||||
    DESTINATION "${CMAKE_INSTALL_CMAKEDIR}"
 | 
			
		||||
    FILE "CalamaresTargets.cmake"
 | 
			
		||||
    NAMESPACE Calamares::
 | 
			
		||||
)
 | 
			
		||||
install(EXPORT Calamares DESTINATION "${CMAKE_INSTALL_CMAKEDIR}" FILE "CalamaresTargets.cmake" NAMESPACE Calamares::)
 | 
			
		||||
 | 
			
		||||
# Install the cmake files
 | 
			
		||||
install(
 | 
			
		||||
@@ -602,69 +662,61 @@ install(
 | 
			
		||||
        "CMakeModules/CalamaresCheckModuleSelection.cmake"
 | 
			
		||||
        "CMakeModules/CMakeColors.cmake"
 | 
			
		||||
        "CMakeModules/FindYAMLCPP.cmake"
 | 
			
		||||
    DESTINATION
 | 
			
		||||
        "${CMAKE_INSTALL_CMAKEDIR}"
 | 
			
		||||
    DESTINATION "${CMAKE_INSTALL_CMAKEDIR}"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
### Miscellaneous installs
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
if( INSTALL_CONFIG )
 | 
			
		||||
    install(
 | 
			
		||||
        FILES settings.conf
 | 
			
		||||
        DESTINATION share/calamares
 | 
			
		||||
    )
 | 
			
		||||
if(INSTALL_POLKIT)
 | 
			
		||||
    install(FILES com.github.calamares.calamares.policy DESTINATION "${POLKITQT-1_POLICY_FILES_INSTALL_DIR}")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if( INSTALL_POLKIT )
 | 
			
		||||
    install(
 | 
			
		||||
        FILES com.github.calamares.calamares.policy
 | 
			
		||||
        DESTINATION "${POLKITQT-1_POLICY_FILES_INSTALL_DIR}"
 | 
			
		||||
    )
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if ( INSTALL_COMPLETION )
 | 
			
		||||
    if( NOT CMAKE_INSTALL_BASHCOMPLETIONDIR )
 | 
			
		||||
        set( CMAKE_INSTALL_BASHCOMPLETIONDIR "${CMAKE_INSTALL_DATADIR}/bash-completion/completions" )
 | 
			
		||||
if(INSTALL_COMPLETION)
 | 
			
		||||
    if(NOT CMAKE_INSTALL_BASHCOMPLETIONDIR)
 | 
			
		||||
        set(CMAKE_INSTALL_BASHCOMPLETIONDIR "${CMAKE_INSTALL_DATADIR}/bash-completion/completions")
 | 
			
		||||
    endif()
 | 
			
		||||
 | 
			
		||||
    install( FILES ${CMAKE_SOURCE_DIR}/data/completion/bash/calamares DESTINATION "${CMAKE_INSTALL_BASHCOMPLETIONDIR}" )
 | 
			
		||||
    install(FILES ${CMAKE_SOURCE_DIR}/data/completion/bash/calamares DESTINATION "${CMAKE_INSTALL_BASHCOMPLETIONDIR}")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
install(
 | 
			
		||||
  FILES calamares.desktop
 | 
			
		||||
  DESTINATION ${CMAKE_INSTALL_DATADIR}/applications
 | 
			
		||||
)
 | 
			
		||||
install(FILES calamares.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
 | 
			
		||||
 | 
			
		||||
install(
 | 
			
		||||
    FILES man/calamares.8
 | 
			
		||||
    DESTINATION ${CMAKE_INSTALL_MANDIR}/man8/
 | 
			
		||||
)
 | 
			
		||||
install(FILES man/calamares.8 DESTINATION ${CMAKE_INSTALL_MANDIR}/man8/)
 | 
			
		||||
 | 
			
		||||
# uninstall target
 | 
			
		||||
if(INSTALL_CONFIG)
 | 
			
		||||
    install(FILES settings.conf DESTINATION share/calamares)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
### Uninstall
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
configure_file(
 | 
			
		||||
    "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
 | 
			
		||||
    "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
 | 
			
		||||
    IMMEDIATE @ONLY
 | 
			
		||||
    IMMEDIATE
 | 
			
		||||
    @ONLY
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
add_custom_target( uninstall
 | 
			
		||||
    COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake
 | 
			
		||||
)
 | 
			
		||||
add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
 | 
			
		||||
 | 
			
		||||
### Developer convenience
 | 
			
		||||
#
 | 
			
		||||
# The module support files -- .desc files, .conf files -- are copied into the build
 | 
			
		||||
# directory so that it is possible to run `calamares -d` from there. Copy the
 | 
			
		||||
# top-level settings.conf as well, into the build directory.
 | 
			
		||||
if( settings.conf IS_NEWER_THAN ${CMAKE_BINARY_DIR}/settings.conf )
 | 
			
		||||
    configure_file(settings.conf ${CMAKE_BINARY_DIR}/settings.conf COPYONLY)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### CMAKE SUMMARY REPORT
 | 
			
		||||
#
 | 
			
		||||
get_directory_property( SKIPPED_MODULES
 | 
			
		||||
    DIRECTORY src/modules
 | 
			
		||||
    DEFINITION LIST_SKIPPED_MODULES
 | 
			
		||||
)
 | 
			
		||||
get_directory_property(SKIPPED_MODULES DIRECTORY src/modules DEFINITION LIST_SKIPPED_MODULES)
 | 
			
		||||
calamares_explain_skipped_modules( ${SKIPPED_MODULES} )
 | 
			
		||||
 | 
			
		||||
feature_summary(
 | 
			
		||||
    WHAT DISABLED_FEATURES
 | 
			
		||||
    DESCRIPTION "The following features have been disabled:"
 | 
			
		||||
    QUIET_ON_EMPTY
 | 
			
		||||
)
 | 
			
		||||
feature_summary(WHAT DISABLED_FEATURES DESCRIPTION "The following features have been disabled:" QUIET_ON_EMPTY)
 | 
			
		||||
feature_summary(
 | 
			
		||||
    WHAT OPTIONAL_PACKAGES_NOT_FOUND
 | 
			
		||||
    DESCRIPTION "The following OPTIONAL packages were not found:"
 | 
			
		||||
@@ -681,11 +733,11 @@ feature_summary(
 | 
			
		||||
#
 | 
			
		||||
# Note: most distro's will do distro-specific packaging rather than
 | 
			
		||||
#       using CPack, and this duplicates information in the AppStream, too.
 | 
			
		||||
# TODO:3.3 With newer CMake, move HOMEPAGE_URL to the project()call
 | 
			
		||||
set(CPACK_PACKAGE_VENDOR calamares)
 | 
			
		||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "A Linux system installer")
 | 
			
		||||
set(CPACK_PACKAGE_DESCRIPTION "Calamares is a Linux system installer, intended for Linux distributions to use on their ISOs and other bootable media to install the distribution to the end-user's computer. Calamares can also be used as an OEM configuration tool. It is modular, extensible and highly-configurable for Linux distributions from all five major Linux families.")
 | 
			
		||||
set(CPACK_PACKAGE_HOMEPAGE_URL "https://calamares.io")
 | 
			
		||||
set(CPACK_PACKAGE_DESCRIPTION
 | 
			
		||||
    "Calamares is a Linux system installer, intended for Linux distributions to use on their ISOs and other bootable media to install the distribution to the end-user's computer. Calamares can also be used as an OEM configuration tool. It is modular, extensible and highly-configurable for Linux distributions from all five major Linux families."
 | 
			
		||||
)
 | 
			
		||||
set(CPACK_PACKAGE_ICON "data/images/squid.png")
 | 
			
		||||
 | 
			
		||||
include(CPack)
 | 
			
		||||
 
 | 
			
		||||
@@ -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()
 | 
			
		||||
@@ -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})
 | 
			
		||||
 
 | 
			
		||||
@@ -121,7 +121,8 @@ function( _calamares_add_module_subdirectory_impl )
 | 
			
		||||
        # _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" )
 | 
			
		||||
@@ -152,12 +153,10 @@ function( _calamares_add_module_subdirectory_impl )
 | 
			
		||||
 | 
			
		||||
                    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()
 | 
			
		||||
@@ -168,12 +167,14 @@ function( _calamares_add_module_subdirectory_impl )
 | 
			
		||||
            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
 | 
			
		||||
 
 | 
			
		||||
@@ -104,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]" )
 | 
			
		||||
@@ -210,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,19 +18,17 @@
 | 
			
		||||
#   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
 | 
			
		||||
@@ -38,17 +36,20 @@ function( calamares_add_test )
 | 
			
		||||
            LINK_LIBRARIES
 | 
			
		||||
                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} Calamares::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()
 | 
			
		||||
 
 | 
			
		||||
@@ -57,11 +57,6 @@ function( extend_version version short_only short_var long_var )
 | 
			
		||||
    set( ${short_var} "${version}" PARENT_SCOPE )
 | 
			
		||||
    set( _v "${version}" )
 | 
			
		||||
    if ( NOT short_only )
 | 
			
		||||
        # Additional info for non-release builds which want "long" version info
 | 
			
		||||
        # with date and git information (commit, dirty status). That is used only
 | 
			
		||||
        # by CalamaresVersionX.h, which is included by consumers that need a full
 | 
			
		||||
        # version number with all that information; normal consumers can include
 | 
			
		||||
        # CalamaresVersion.h with more stable numbers.
 | 
			
		||||
        string( TIMESTAMP CALAMARES_VERSION_DATE "%Y%m%d" )
 | 
			
		||||
        if( CALAMARES_VERSION_DATE GREATER 0 )
 | 
			
		||||
            set( _v ${_v}.${CALAMARES_VERSION_DATE} )
 | 
			
		||||
 
 | 
			
		||||
@@ -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()
 | 
			
		||||
@@ -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,18 +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 in a [Matrix](https://matrix.org/)
 | 
			
		||||
room, `#calamares:kde.org`. The conversation is bridged with IRC
 | 
			
		||||
on [Libera.Chat](https://libera.chat/).
 | 
			
		||||
Responsiveness is best during the day
 | 
			
		||||
in Europe, but feel free to idle. If you use IRC, **DO NOT** ask-and-leave. Keep
 | 
			
		||||
that chat window open because it can easily take a few hours for
 | 
			
		||||
someone to notice a message.
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
**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)
 | 
			
		||||
* [](https://kiwiirc.com/client/irc.libera.chat/#calamares)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## General Guidelines
 | 
			
		||||
@@ -57,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
 | 
			
		||||
@@ -74,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)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -46,20 +46,27 @@ 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(INSERT CMAKE_MODULE_PATH 0 ${ECM_MODULE_PATH})
 | 
			
		||||
        find_package(KF5 REQUIRED COMPONENTS ${kf5_required})
 | 
			
		||||
        find_package(${kfname} REQUIRED COMPONENTS ${kf5_required})
 | 
			
		||||
    endif()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
@@ -87,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,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
									
									
									
									
									
								
							@@ -7,26 +7,26 @@
 | 
			
		||||
 | 
			
		||||
[](https://github.com/calamares/calamares/labels/hacking%3A%20in-progress)
 | 
			
		||||
[](https://github.com/calamares/calamares/releases)
 | 
			
		||||
[](https://github.com/calamares/calamares/actions?query=workflow%3Aci)
 | 
			
		||||
[](https://github.com/calamares/calamares/blob/calamares/LICENSES/GPL-3.0-or-later.txt)
 | 
			
		||||
[](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) | [Matrix: #calamares:kde.org](https://webchat.kde.org/#/room/%23calamares:kde.org) | [IRC: Libera.Chat #calamares](https://kiwiirc.com/client/irc.libera.chat/#calamares) | [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://calamares.io/docs/users-guide/)
 | 
			
		||||
for end-users, but most of what we have is for distro developers.
 | 
			
		||||
@@ -45,25 +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),
 | 
			
		||||
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 in a [Matrix](https://matrix.org/)
 | 
			
		||||
room, `#calamares:kde.org`. The conversation is bridged with IRC
 | 
			
		||||
on [Libera.Chat](https://libera.chat/).
 | 
			
		||||
Responsiveness is best during the day
 | 
			
		||||
in Europe, but feel free to idle. If you use IRC, **DO NOT** ask-and-leave. Keep
 | 
			
		||||
that chat window open because it can easily take a few hours for
 | 
			
		||||
someone to notice a message.
 | 
			
		||||
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)
 | 
			
		||||
* [](https://kiwiirc.com/client/irc.libera.chat/#calamares)
 | 
			
		||||
* [](https://webchat.kde.org/#/room/%23calamares:kde.org) (needs a Matrix account)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -76,7 +76,7 @@ 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
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,8 +7,6 @@
 | 
			
		||||
#
 | 
			
		||||
# Release script for Calamares
 | 
			
		||||
#
 | 
			
		||||
# NOTE: this script contains Linuxisms (in particular, expects GNU mktemp(1))
 | 
			
		||||
#
 | 
			
		||||
# This attempts to perform the different steps of the RELEASE.md
 | 
			
		||||
# document automatically. It's not tested on other machines or
 | 
			
		||||
# setups other than [ade]'s development VM.
 | 
			
		||||
@@ -29,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
 | 
			
		||||
 | 
			
		||||
@@ -45,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"
 | 
			
		||||
@@ -57,6 +58,9 @@ while getopts "hBPT" opt ; do
 | 
			
		||||
        BUILD_DEFAULT=false
 | 
			
		||||
        BUILD_CLANG=false
 | 
			
		||||
        ;;
 | 
			
		||||
    b)
 | 
			
		||||
	TEST_TARBALL=false
 | 
			
		||||
	;;
 | 
			
		||||
    P)
 | 
			
		||||
        BUILD_ONLY=true
 | 
			
		||||
        ;;
 | 
			
		||||
@@ -74,7 +78,7 @@ 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
 | 
			
		||||
@@ -82,6 +86,16 @@ KEY_ID="328D742D8807A435"
 | 
			
		||||
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
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
@@ -120,12 +134,6 @@ 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,
 | 
			
		||||
@@ -144,12 +152,14 @@ 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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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
 | 
			
		||||
@@ -9,7 +9,7 @@ indent=spaces=4
 | 
			
		||||
 | 
			
		||||
# Brackets
 | 
			
		||||
style=break
 | 
			
		||||
add-brackets
 | 
			
		||||
add-braces
 | 
			
		||||
 | 
			
		||||
# Spaces
 | 
			
		||||
pad-paren-in
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										20
									
								
								ci/build.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										20
									
								
								ci/build.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
#! /bin/sh
 | 
			
		||||
#
 | 
			
		||||
# Generic build (driven by environment variables)
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
# Sanity check
 | 
			
		||||
test -n "$BUILDDIR" || { echo "! \$BUILDDIR not set" ; exit 1 ; }
 | 
			
		||||
mkdir -p "$BUILDDIR"
 | 
			
		||||
test -f "$SRCDIR/CMakeLists.txt" || { echo "! Missing $SRCDIR/CMakeLists.txt" ; exit 1 ; }
 | 
			
		||||
 | 
			
		||||
BUILD_MESSAGE="No commit info"
 | 
			
		||||
test -n "$GIT_HASH" && BUILD_MESSAGE=$( git log -1 --abbrev-commit --pretty=oneline --no-decorate "$GIT_HASH" )
 | 
			
		||||
 | 
			
		||||
echo "::" ; echo ":: $BUILD_MESSAGE" ; echo "::"
 | 
			
		||||
 | 
			
		||||
cmake -S "$SRCDIR" -B "$BUILDDIR" -G Ninja $CMAKE_ARGS || exit 1
 | 
			
		||||
ninja -C "$BUILDDIR" || exit 1
 | 
			
		||||
ninja -C "$BUILDDIR" install || exit 1
 | 
			
		||||
 | 
			
		||||
echo "::" ; echo ":: $BUILD_MESSAGE" ; echo "::"
 | 
			
		||||
@@ -4,8 +4,7 @@
 | 
			
		||||
#   SPDX-FileCopyrightText: 2019 Adriaan de Groot <groot@kde.org>
 | 
			
		||||
#   SPDX-License-Identifier: BSD-2-Clause
 | 
			
		||||
#
 | 
			
		||||
# Calls astyle with settings matching Calamares coding style
 | 
			
		||||
# Requires astyle >= 2.04 and clang-format-8 or later
 | 
			
		||||
# Apply Calamares-style formatting to sources. Requires clang-format-15.
 | 
			
		||||
#
 | 
			
		||||
# You can pass in directory names, in which case the files
 | 
			
		||||
# in that directory (NOT below it) are processed.
 | 
			
		||||
@@ -21,10 +20,8 @@ test -d "$BASEDIR" || { echo "! Could not determine base for $0" ; exit 1 ; }
 | 
			
		||||
test -d "$TOPDIR" || { echo "! Cound not determine top-level source dir" ; exit 1 ; }
 | 
			
		||||
test -f "$TOPDIR/.clang-format" || { echo "! No .clang-format support files in $TOPDIR" ; exit 1 ; }
 | 
			
		||||
 | 
			
		||||
AS=$( which astyle )
 | 
			
		||||
 | 
			
		||||
# Allow specifying CF_VERSIONS outside already
 | 
			
		||||
CF_VERSIONS="$CF_VERSIONS clang-format13 clang-format-13 clang-format12 clang-format-12 clang-format"
 | 
			
		||||
CF_VERSIONS="$CF_VERSIONS clang-format15 clang-format-15 clang-format-16 clang-format-16.0.6 clang-format"
 | 
			
		||||
for _cf in $CF_VERSIONS
 | 
			
		||||
do
 | 
			
		||||
	# Not an error if this particular clang-format isn't found
 | 
			
		||||
@@ -32,24 +29,30 @@ do
 | 
			
		||||
	test -n "$CF" && break
 | 
			
		||||
done
 | 
			
		||||
 | 
			
		||||
test -n "$AS" || { echo "! No astyle found in PATH"; exit 1 ; }
 | 
			
		||||
test -n "$CF" || { echo "! No clang-format ($CF_VERSIONS) found in PATH"; exit 1 ; }
 | 
			
		||||
test -x "$AS" || { echo "! $AS is not executable."; exit 1 ; }
 | 
			
		||||
test -x "$CF" || { echo "! $CF is not executable."; exit 1 ; }
 | 
			
		||||
 | 
			
		||||
### CLANG-FORMAT-WRANGLING
 | 
			
		||||
#
 | 
			
		||||
# Version 7 and earlier doesn't understand all the options we would like
 | 
			
		||||
# Version 12 handles lambdas nicely, so use that.
 | 
			
		||||
# Version 13 is also ok.
 | 
			
		||||
# Version 7 and earlier doesn't understand all the options we would like.
 | 
			
		||||
# Version 12 handled lambdas nicely and was the norm for Calamares 3.2.
 | 
			
		||||
# Version 13 was also ok.
 | 
			
		||||
# Version 14 behaves differently with short-functions-in-class,
 | 
			
		||||
#   spreading functions out that 13 keeps on one line. To avoid
 | 
			
		||||
#   ping-pong commits, forbid 14.
 | 
			
		||||
# Version 15 is available on recent-ish Ubuntus and FreeBSD, pick it.
 | 
			
		||||
#   It also supports inserting braces, which is the one thing we kept
 | 
			
		||||
#   astyle around for.
 | 
			
		||||
# Version 16 is available on openSUSE and is ok as well.
 | 
			
		||||
# Version 17 is available on FreeBSD and KaOS and is ok as well.
 | 
			
		||||
 | 
			
		||||
format_version=`"$CF" --version | tr -dc '[^.0-9]' | cut  -d . -f 1`
 | 
			
		||||
case "$format_version" in
 | 
			
		||||
	12|13 )
 | 
			
		||||
	15|16|17 )
 | 
			
		||||
		:
 | 
			
		||||
		;;
 | 
			
		||||
	* )
 | 
			
		||||
		echo "! Clang-format version '$format_version' unsupported, version 12 required."
 | 
			
		||||
		echo "! Clang-format version '$format_version' unsupported, versions 15-17 are ok."
 | 
			
		||||
		exit 1
 | 
			
		||||
		;;
 | 
			
		||||
esac
 | 
			
		||||
@@ -69,7 +72,6 @@ done
 | 
			
		||||
style_some()
 | 
			
		||||
{
 | 
			
		||||
	if test -n "$*" ; then
 | 
			
		||||
		$AS --options=$BASEDIR/astylerc --quiet "$@"
 | 
			
		||||
		$CF -i -style=file "$@"
 | 
			
		||||
	fi
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -48,7 +48,6 @@ ERR_IMPORT, ERR_USAGE, ERR_FILE_NOT_FOUND, ERR_SYNTAX, ERR_INVALID = range(1,6)
 | 
			
		||||
#
 | 
			
		||||
try:
 | 
			
		||||
    from jsonschema import validate, SchemaError, ValidationError
 | 
			
		||||
    from jsonschema import draft7_format_checker
 | 
			
		||||
    from yaml import safe_load, YAMLError
 | 
			
		||||
except ImportError as e:
 | 
			
		||||
    print(e)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										46
									
								
								ci/deps-debian11.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										46
									
								
								ci/deps-debian11.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
#! /bin/sh
 | 
			
		||||
#
 | 
			
		||||
# Install dependencies for the nightly-debian (11) build
 | 
			
		||||
#
 | 
			
		||||
apt-get update
 | 
			
		||||
apt-get -y install git-core jq curl ninja
 | 
			
		||||
apt-get -y install \
 | 
			
		||||
	build-essential \
 | 
			
		||||
	cmake \
 | 
			
		||||
	extra-cmake-modules \
 | 
			
		||||
	gettext \
 | 
			
		||||
	libatasmart-dev \
 | 
			
		||||
	libappstreamqt-dev \
 | 
			
		||||
	libboost-python-dev \
 | 
			
		||||
	libicu-dev \
 | 
			
		||||
	libparted-dev \
 | 
			
		||||
	libpolkit-qt5-1-dev \
 | 
			
		||||
	libqt5svg5-dev \
 | 
			
		||||
	libqt5webkit5-dev \
 | 
			
		||||
	libyaml-cpp-dev \
 | 
			
		||||
	ninja-build \
 | 
			
		||||
	os-prober \
 | 
			
		||||
	pkg-config \
 | 
			
		||||
	python3-dev \
 | 
			
		||||
	qtbase5-dev \
 | 
			
		||||
	qtdeclarative5-dev \
 | 
			
		||||
	qttools5-dev \
 | 
			
		||||
	qttools5-dev-tools
 | 
			
		||||
# Same name as on KDE neon, different version
 | 
			
		||||
apt-get -y install libkpmcore-dev
 | 
			
		||||
# Additional dependencies (KF5, +)
 | 
			
		||||
apt-get -y install \
 | 
			
		||||
	libkf5config-dev \
 | 
			
		||||
	libkf5coreaddons-dev \
 | 
			
		||||
	libkf5i18n-dev \
 | 
			
		||||
	libkf5iconthemes-dev \
 | 
			
		||||
	libkf5parts-dev \
 | 
			
		||||
	libkf5service-dev \
 | 
			
		||||
	libkf5solid-dev \
 | 
			
		||||
	libkf5crash-dev \
 | 
			
		||||
	libkf5package-dev \
 | 
			
		||||
	libkf5plasma-dev \
 | 
			
		||||
	libpwquality-dev \
 | 
			
		||||
	libqt5webenginewidgets5 \
 | 
			
		||||
	qtwebengine5-dev
 | 
			
		||||
true
 | 
			
		||||
							
								
								
									
										11
									
								
								ci/deps-endeavouros.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										11
									
								
								ci/deps-endeavouros.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
#! /bin/sh
 | 
			
		||||
#
 | 
			
		||||
# Install dependencies for building on EndeavourOS
 | 
			
		||||
#
 | 
			
		||||
# There is no docker image for EndeavoudOS, and the live ISO
 | 
			
		||||
# for Cassini Nova is KF5 / Qt5 based, but we can build there.
 | 
			
		||||
# It even has most of the build-deps already installed.
 | 
			
		||||
pacman -Syu --noconfirm git cmake ninja jq
 | 
			
		||||
pacman -S --noconfirm gcc yaml-cpp icu
 | 
			
		||||
pacman -S --noconfigm extra-cmake-modules
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										17
									
								
								ci/deps-fedora-qt6.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										17
									
								
								ci/deps-fedora-qt6.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
#! /bin/sh
 | 
			
		||||
#
 | 
			
		||||
# Install dependencies for the nightly-fedora-qt6 build
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
yum install -y bison flex git make cmake gcc-c++ ninja-build
 | 
			
		||||
yum install -y yaml-cpp-devel libpwquality-devel parted-devel python-devel gettext gettext-devel
 | 
			
		||||
yum install -y libicu-devel libatasmart-devel
 | 
			
		||||
# Qt6/KF6 dependencies
 | 
			
		||||
yum install -y qt6-qtbase-devel qt6-linguist qt6-qtbase-private-devel qt6-qtdeclarative-devel qt6-qtsvg-devel qt6-qttools-devel
 | 
			
		||||
yum install -y extra-cmake-modules kf6-kcoreaddons-devel kf6-kdbusaddons-devel kf6-kcrash-devel
 | 
			
		||||
yum install -y kf6-kconfig-devel kf6-ki18n-devel kf6-kwidgetsaddons-devel kf6-kservice-devel
 | 
			
		||||
yum install -y polkit-qt6-1-devel appstream-qt-devel
 | 
			
		||||
# Runtime dependencies for QML modules
 | 
			
		||||
yum install -y kf6-kirigami2-devel || true
 | 
			
		||||
yum install -y qt6-qt5compat-devel || true
 | 
			
		||||
true
 | 
			
		||||
							
								
								
									
										25
									
								
								ci/deps-kaos.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										25
									
								
								ci/deps-kaos.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
#! /bin/sh
 | 
			
		||||
#
 | 
			
		||||
# Install dependencies for building on KaOS
 | 
			
		||||
#
 | 
			
		||||
# There is no docker image for KaOS, and the live ISO comes
 | 
			
		||||
# with many useful things already installed, so the list
 | 
			
		||||
# here is short. Use pacman -Syu once to update the whole
 | 
			
		||||
# system to get latest libraries.
 | 
			
		||||
#
 | 
			
		||||
pacman -Syu --noconfirm git cmake ninja # No jq available
 | 
			
		||||
pacman -S --noconfirm \
 | 
			
		||||
	"gcc" \
 | 
			
		||||
	"boost" \
 | 
			
		||||
	"qt5-tools" \
 | 
			
		||||
	"yaml-cpp" \
 | 
			
		||||
	"kpmcore" \
 | 
			
		||||
	"icu"
 | 
			
		||||
pacman -S --noconfirm \
 | 
			
		||||
	"extra-cmake-modules" \
 | 
			
		||||
	"kiconthemes" \
 | 
			
		||||
	"kservice" \
 | 
			
		||||
	"kio" \
 | 
			
		||||
	"kparts" \
 | 
			
		||||
	"qtwebengine"
 | 
			
		||||
true
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user